On 06/04/2016 07:38, Amit Kapila wrote:
> On Tue, Apr 5, 2016 at 11:55 PM, Julien Rouhaud
>>
>> In alter_table.sgml, I didn't comment the lock level needed to modify
>> parallel_degree since it requires an access exclusive lock for now.
>> While thinking about it, I think it's safe to use a share update
>> exclusive lock but I may be wrong. What do you think?
>>
>
> We require to keep AccessExclusiveLock for operations which can impact
> Select operation which I think this operation does, so lets
> retain AccessExclusiveLock for now. If somebody else thinks, we should
> not bother about Selects, then we can change it.
>
Ok. Isn't there also some considerations about forcing replanning of
prepared statements using the table for instance?
>>
>> I find your version better once again, but should we keep some
>> consistency between them or it's not important?
>>
>
> I think consistency is good, but this is different from
> max_parallel_degree, so I would prefer to use something on lines of what
> I have mentioned.
>
Agreed, changed in attached v8 (including fix for previous mail).
--
Julien Rouhaud
http://dalibo.com - http://dalibo.org
diff --git a/doc/src/sgml/ref/create_table.sgml
b/doc/src/sgml/ref/create_table.sgml
index cd234db..0eab2be 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -909,6 +909,17 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } |
UNLOGGED ] TABLE [ IF NOT EXI
</varlistentry>
<varlistentry>
+ <term><literal>parallel_degree</> (<type>integer</>)</term>
+ <listitem>
+ <para>
+ Sets the degree of parallelism for an individual relation. The requested
+ number of workers will be limited by <xref
+ linkend="guc-max-parallel-degree">.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><literal>autovacuum_enabled</>,
<literal>toast.autovacuum_enabled</literal> (<type>boolean</>)</term>
<listitem>
<para>
diff --git a/src/backend/access/common/reloptions.c
b/src/backend/access/common/reloptions.c
index ea0755a..758457c 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -26,6 +26,7 @@
#include "commands/tablespace.h"
#include "commands/view.h"
#include "nodes/makefuncs.h"
+#include "postmaster/postmaster.h"
#include "utils/array.h"
#include "utils/attoptcache.h"
#include "utils/builtins.h"
@@ -267,6 +268,15 @@ static relopt_int intRelOpts[] =
0, 0, 0
#endif
},
+ {
+ {
+ "parallel_degree",
+ "Number of parallel processes that can be used per
executor node for this relation.",
+ RELOPT_KIND_HEAP,
+ AccessExclusiveLock
+ },
+ -1, 0, MAX_BACKENDS
+ },
/* list terminator */
{{NULL}}
@@ -1251,8 +1261,8 @@ fillRelOptions(void *rdopts, Size basesize,
/*
- * Option parser for anything that uses StdRdOptions (i.e. fillfactor and
- * autovacuum)
+ * Option parser for anything that uses StdRdOptions (i.e. fillfactor,
+ * autovacuum and parallel_degree)
*/
bytea *
default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
@@ -1291,7 +1301,9 @@ default_reloptions(Datum reloptions, bool validate,
relopt_kind kind)
{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts,
analyze_scale_factor)},
{"user_catalog_table", RELOPT_TYPE_BOOL,
- offsetof(StdRdOptions, user_catalog_table)}
+ offsetof(StdRdOptions, user_catalog_table)},
+ {"parallel_degree", RELOPT_TYPE_INT,
+ offsetof(StdRdOptions, parallel_degree)}
};
options = parseRelOptions(reloptions, validate, kind, &numoptions);
diff --git a/src/backend/optimizer/path/allpaths.c
b/src/backend/optimizer/path/allpaths.c
index cc77ff9..38233bc 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -659,31 +659,42 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo
*rel, RangeTblEntry *rte)
static void
create_parallel_paths(PlannerInfo *root, RelOptInfo *rel)
{
- int parallel_threshold = 1000;
- int parallel_degree = 1;
+ int parallel_threshold = 1000;
+ int parallel_degree = 1;
/*
* If this relation is too small to be worth a parallel scan, just
return
- * without doing anything ... unless it's an inheritance child. In
that case,
- * we want to generate a parallel path here anyway. It might not be
worthwhile
- * just for this relation, but when combined with all of its
inheritance siblings
- * it may well pay off.
+ * without doing anything ... unless parallel_degree has been set for
this
+ * relation, or if it's an inheritance child. In the latter case, we
want
+ * to generate a parallel path here anyway. It might not be worthwhile
+ * just for this relation, but when combined with all of its inheritance
+ * siblings it may well pay off.
*/
- if (rel->pages < parallel_threshold && rel->reloptkind ==
RELOPT_BASEREL)
+ if (rel->pages < parallel_threshold && rel->rel_parallel_degree == -1 &&
+ rel->reloptkind == RELOPT_BASEREL)
return;
/*
- * Limit the degree of parallelism logarithmically based on the size of
the
- * relation. This probably needs to be a good deal more sophisticated,
but we
- * need something here for now.
+ * Use the table parallel_degree if specified, but don't go further than
+ * max_parallel_degree
*/
- while (rel->pages > parallel_threshold * 3 &&
- parallel_degree < max_parallel_degree)
+ if (rel->rel_parallel_degree > 0)
+ parallel_degree = Min(rel->rel_parallel_degree,
max_parallel_degree);
+ else
{
- parallel_degree++;
- parallel_threshold *= 3;
- if (parallel_threshold >= PG_INT32_MAX / 3)
- break;
+ /*
+ * Limit the degree of parallelism logarithmically based on the
size
+ * of the relation. This probably needs to be a good deal more
+ * sophisticated, but we need something here for now.
+ */
+ while (rel->pages > parallel_threshold * 3 &&
+ parallel_degree < max_parallel_degree)
+ {
+ parallel_degree++;
+ parallel_threshold *= 3;
+ if (parallel_threshold >= PG_INT32_MAX / 3)
+ break;
+ }
}
/* Add an unordered partial path based on a parallel sequential scan. */
diff --git a/src/backend/optimizer/util/plancat.c
b/src/backend/optimizer/util/plancat.c
index 5bdeac0..68ce936 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -128,6 +128,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId,
bool inhparent,
estimate_rel_size(relation, rel->attr_widths - rel->min_attr,
&rel->pages, &rel->tuples,
&rel->allvisfrac);
+ /* Setup the per-relation parallel_degree */
+ rel->rel_parallel_degree = RelationGetParallelDegree(relation, -1);
/*
* Make list of indexes. Ignore indexes on system catalogs if told to.
* Don't bother with indexes for an inheritance parent, either.
diff --git a/src/backend/optimizer/util/relnode.c
b/src/backend/optimizer/util/relnode.c
index 6f24b03..2175de3 100644
--- a/src/backend/optimizer/util/relnode.c
+++ b/src/backend/optimizer/util/relnode.c
@@ -107,6 +107,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind
reloptkind)
rel->consider_startup = (root->tuple_fraction > 0);
rel->consider_param_startup = false; /* might get changed
later */
rel->consider_parallel = false; /* might get changed later */
+ rel->rel_parallel_degree = -1; /* set up in GetRelationInfo */
rel->reltarget = create_empty_pathtarget();
rel->pathlist = NIL;
rel->ppilist = NIL;
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index cb8a06d..6d09271 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1783,6 +1783,7 @@ psql_completion(const char *text, int start, int end)
"autovacuum_vacuum_scale_factor",
"autovacuum_vacuum_threshold",
"fillfactor",
+ "parallel_degree",
"log_autovacuum_min_duration",
"toast.autovacuum_enabled",
"toast.autovacuum_freeze_max_age",
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index d39c73b..72fc91f 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -521,6 +521,7 @@ typedef struct RelOptInfo
double allvisfrac;
PlannerInfo *subroot; /* if subquery */
List *subplan_params; /* if subquery */
+ int rel_parallel_degree; /* wanted number of
parallel workers */
/* Information about foreign tables and foreign joins */
Oid serverid; /* identifies server
for the table or join */
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index f2bebf2..5443084 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -203,6 +203,7 @@ typedef struct StdRdOptions
AutoVacOpts autovacuum; /* autovacuum-related options */
bool user_catalog_table; /* use as an additional
catalog
* relation */
+ int parallel_degree; /* max number of parallel
workers */
} StdRdOptions;
#define HEAP_MIN_FILLFACTOR 10
@@ -217,6 +218,14 @@ typedef struct StdRdOptions
((StdRdOptions *) (relation)->rd_options)->fillfactor : (defaultff))
/*
+ * RelationGetParallelDegree
+ * Returns the relation's parallel_degree. Note multiple eval of
argument!
+ */
+#define RelationGetParallelDegree(relation, defaultpd) \
+ ((relation)->rd_options ? \
+ ((StdRdOptions *) (relation)->rd_options)->parallel_degree :
(defaultpd))
+
+/*
* RelationGetTargetPageUsage
* Returns the relation's desired space usage per page in bytes.
*/
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers