On 04/04/2016 08:55, Amit Kapila wrote:

Thanks for the review!

> Few comments:
> 1.
> +      limited according to the <xref linkend="gux-max-parallel-degree">
> 
> A. typo.
>    /gux-max-parallel-degree/guc-max-parallel-degree
>    /worker/workers

Oops, fixed.

> B. +     <para>
> +      Number of workers wanted for this table. The number of worker will be
> +      limited according to 
> the <xref linkend="gux-max-parallel-degree">
> +      parameter.
> +     </para>
> 
> How about writing the above as:
> Sets the degree of parallelism for an individual relation.  The
> requested number of workers will be limited by <xref
> linkend="guc-max-parallel-degree">
> 

That's clearly better, changed.

> 2.
> +{
> +{
> +"parallel_degree",
> +"Number of parallel processes 
> per executor node wanted for this relation.",
> +RELOPT_KIND_HEAP,
> +
> AccessExclusiveLock
> +},
> +-1, 1, INT_MAX
> +},
> 
> I think here min and max values should be same as for
> max_parallel_degree (I have verified that for some of the other
> reloption parameters, min and max are same as their guc values); Is
> there a reason to keep them different?
> 

No reason. I put 0 and MAX_BACKENDS, as the GUC value.

> 3.
> @@ -1291,7 +1300,9 @@ default_reloptions(Datum reloptions, bool
> validate, relopt_kind kind)
> 
> Comment on top of this function says:
> /*
>  * Option parser for anything that uses StdRdOptions (i.e. fillfactor and
>  * autovacuum)
>  */
> 
> I think it is better to include parallel_degree in above comment along
> with fillfactor and autovacuum.
> 

Agreed. BTW the user_catalog_table option isn't listed either.

> 
> 4.
> /*
> + * RelationGetMaxParallelDegree
> + *Returns the relation's parallel_degree.  Note multiple eval of 
> argument!
> + */
> +#define RelationGetParallelDegree(relation, defaultmpd) \
> +((relation)->rd_options ? \
> + 
> ((StdRdOptions *) (relation)->rd_options)->parallel_degree : (defaultmpd))
> +
> 
> There are minor in-consistencies in the above macro definition.
> 
> a. RelationGetMaxParallelDegree - This should be RelationGetParallelDegree.
> b. defaultmpd - it is better to name it as defaultpd
> 

Yes, I forgot to update it when I renamed the option, fixed.

>  
>>
>>
>> The feature freeze is now very close.  If this GUC is still wanted,
>> should I add this patch to the next commitfest?
>>
> 
> I am hoping that this will be committed to 9.6, but I think it is good
> to register it in next CF.
> 

So attached v6 fixes all the problems above.

I'll add it to the next commitfest.

> 
> With Regards,
> Amit Kapila.
> EnterpriseDB: http://www.enterprisedb.com <http://www.enterprisedb.com/>

-- 
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..175b2c6 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="gux-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..8e4aa80 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 per executor node wanted 
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..6032b95 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -669,21 +669,31 @@ create_parallel_paths(PlannerInfo *root, RelOptInfo *rel)
         * 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 688d92a..2e102e7 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..8f1cd85 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 
worker */
 } 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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to