Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 25fe8b5

Browse files
committed
Add a 'parallel_degree' reloption.
The code that estimates what parallel degree should be uesd for the scan of a relation is currently rather stupid, so add a parallel_degree reloption that can be used to override the planner's rather limited judgement. Julien Rouhaud, reviewed by David Rowley, James Sewell, Amit Kapila, and me. Some further hacking by me.
1 parent b0b64f6 commit 25fe8b5

File tree

8 files changed

+86
-23
lines changed

8 files changed

+86
-23
lines changed

doc/src/sgml/ref/create_table.sgml

+13
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,19 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
908908
</listitem>
909909
</varlistentry>
910910

911+
<varlistentry>
912+
<term><literal>parallel_degree</> (<type>integer</>)</term>
913+
<listitem>
914+
<para>
915+
The parallel degree for a table is the number of workers that should
916+
be used to assist a parallel scan of that table. If not set, the
917+
system will determine a value based on the relation size. The actual
918+
number of workers chosen by the planner may be less, for example due to
919+
the setting of <xref linkend="guc-max-parallel-degree">.
920+
</para>
921+
</listitem>
922+
</varlistentry>
923+
911924
<varlistentry>
912925
<term><literal>autovacuum_enabled</>, <literal>toast.autovacuum_enabled</literal> (<type>boolean</>)</term>
913926
<listitem>

src/backend/access/common/reloptions.c

+14-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "commands/tablespace.h"
2727
#include "commands/view.h"
2828
#include "nodes/makefuncs.h"
29+
#include "postmaster/postmaster.h"
2930
#include "utils/array.h"
3031
#include "utils/attoptcache.h"
3132
#include "utils/builtins.h"
@@ -267,6 +268,15 @@ static relopt_int intRelOpts[] =
267268
0, 0, 0
268269
#endif
269270
},
271+
{
272+
{
273+
"parallel_degree",
274+
"Number of parallel processes that can be used per executor node for this relation.",
275+
RELOPT_KIND_HEAP,
276+
AccessExclusiveLock
277+
},
278+
-1, 0, MAX_BACKENDS
279+
},
270280

271281
/* list terminator */
272282
{{NULL}}
@@ -1251,8 +1261,7 @@ fillRelOptions(void *rdopts, Size basesize,
12511261

12521262

12531263
/*
1254-
* Option parser for anything that uses StdRdOptions (i.e. fillfactor and
1255-
* autovacuum)
1264+
* Option parser for anything that uses StdRdOptions.
12561265
*/
12571266
bytea *
12581267
default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
@@ -1291,7 +1300,9 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
12911300
{"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,
12921301
offsetof(StdRdOptions, autovacuum) +offsetof(AutoVacOpts, analyze_scale_factor)},
12931302
{"user_catalog_table", RELOPT_TYPE_BOOL,
1294-
offsetof(StdRdOptions, user_catalog_table)}
1303+
offsetof(StdRdOptions, user_catalog_table)},
1304+
{"parallel_degree", RELOPT_TYPE_INT,
1305+
offsetof(StdRdOptions, parallel_degree)}
12951306
};
12961307

12971308
options = parseRelOptions(reloptions, validate, kind, &numoptions);

src/backend/optimizer/path/allpaths.c

+44-20
Original file line numberDiff line numberDiff line change
@@ -659,31 +659,55 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
659659
static void
660660
create_parallel_paths(PlannerInfo *root, RelOptInfo *rel)
661661
{
662-
int parallel_threshold = 1000;
663-
int parallel_degree = 1;
662+
int parallel_degree = 1;
664663

665664
/*
666-
* If this relation is too small to be worth a parallel scan, just return
667-
* without doing anything ... unless it's an inheritance child. In that case,
668-
* we want to generate a parallel path here anyway. It might not be worthwhile
669-
* just for this relation, but when combined with all of its inheritance siblings
670-
* it may well pay off.
665+
* If the user has set the parallel_degree reloption, we decide what to do
666+
* based on the value of that option. Otherwise, we estimate a value.
671667
*/
672-
if (rel->pages < parallel_threshold && rel->reloptkind == RELOPT_BASEREL)
673-
return;
668+
if (rel->rel_parallel_degree != -1)
669+
{
670+
/*
671+
* If parallel_degree = 0 is set for this relation, bail out. The
672+
* user does not want a parallel path for this relation.
673+
*/
674+
if (rel->rel_parallel_degree == 0)
675+
return;
674676

675-
/*
676-
* Limit the degree of parallelism logarithmically based on the size of the
677-
* relation. This probably needs to be a good deal more sophisticated, but we
678-
* need something here for now.
679-
*/
680-
while (rel->pages > parallel_threshold * 3 &&
681-
parallel_degree < max_parallel_degree)
677+
/*
678+
* Use the table parallel_degree, but don't go further than
679+
* max_parallel_degree.
680+
*/
681+
parallel_degree = Min(rel->rel_parallel_degree, max_parallel_degree);
682+
}
683+
else
682684
{
683-
parallel_degree++;
684-
parallel_threshold *= 3;
685-
if (parallel_threshold >= PG_INT32_MAX / 3)
686-
break;
685+
int parallel_threshold = 1000;
686+
687+
/*
688+
* If this relation is too small to be worth a parallel scan, just
689+
* return without doing anything ... unless it's an inheritance child.
690+
* In that case, we want to generate a parallel path here anyway. It
691+
* might not be worthwhile just for this relation, but when combined
692+
* with all of its inheritance siblings it may well pay off.
693+
*/
694+
if (rel->pages < parallel_threshold &&
695+
rel->reloptkind == RELOPT_BASEREL)
696+
return;
697+
698+
/*
699+
* Limit the degree of parallelism logarithmically based on the size
700+
* of the relation. This probably needs to be a good deal more
701+
* sophisticated, but we need something here for now.
702+
*/
703+
while (rel->pages > parallel_threshold * 3 &&
704+
parallel_degree < max_parallel_degree)
705+
{
706+
parallel_degree++;
707+
parallel_threshold *= 3;
708+
if (parallel_threshold >= PG_INT32_MAX / 3)
709+
break;
710+
}
687711
}
688712

689713
/* Add an unordered partial path based on a parallel sequential scan. */

src/backend/optimizer/util/plancat.c

+3
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
133133
estimate_rel_size(relation, rel->attr_widths - rel->min_attr,
134134
&rel->pages, &rel->tuples, &rel->allvisfrac);
135135

136+
/* Retrive the parallel_degree reloption, if set. */
137+
rel->rel_parallel_degree = RelationGetParallelDegree(relation, -1);
138+
136139
/*
137140
* Make list of indexes. Ignore indexes on system catalogs if told to.
138141
* Don't bother with indexes for an inheritance parent, either.

src/backend/optimizer/util/relnode.c

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind)
107107
rel->consider_startup = (root->tuple_fraction > 0);
108108
rel->consider_param_startup = false; /* might get changed later */
109109
rel->consider_parallel = false; /* might get changed later */
110+
rel->rel_parallel_degree = -1; /* set up in GetRelationInfo */
110111
rel->reltarget = create_empty_pathtarget();
111112
rel->pathlist = NIL;
112113
rel->ppilist = NIL;

src/bin/psql/tab-complete.c

+1
Original file line numberDiff line numberDiff line change
@@ -1783,6 +1783,7 @@ psql_completion(const char *text, int start, int end)
17831783
"autovacuum_vacuum_scale_factor",
17841784
"autovacuum_vacuum_threshold",
17851785
"fillfactor",
1786+
"parallel_degree",
17861787
"log_autovacuum_min_duration",
17871788
"toast.autovacuum_enabled",
17881789
"toast.autovacuum_freeze_max_age",

src/include/nodes/relation.h

+1
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,7 @@ typedef struct RelOptInfo
522522
double allvisfrac;
523523
PlannerInfo *subroot; /* if subquery */
524524
List *subplan_params; /* if subquery */
525+
int rel_parallel_degree; /* wanted number of parallel workers */
525526

526527
/* Information about foreign tables and foreign joins */
527528
Oid serverid; /* identifies server for the table or join */

src/include/utils/rel.h

+9
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ typedef struct StdRdOptions
206206
AutoVacOpts autovacuum; /* autovacuum-related options */
207207
bool user_catalog_table; /* use as an additional catalog
208208
* relation */
209+
int parallel_degree; /* max number of parallel workers */
209210
} StdRdOptions;
210211

211212
#define HEAP_MIN_FILLFACTOR 10
@@ -242,6 +243,14 @@ typedef struct StdRdOptions
242243
((relation)->rd_options ? \
243244
((StdRdOptions *) (relation)->rd_options)->user_catalog_table : false)
244245

246+
/*
247+
* RelationGetParallelDegree
248+
* Returns the relation's parallel_degree. Note multiple eval of argument!
249+
*/
250+
#define RelationGetParallelDegree(relation, defaultpd) \
251+
((relation)->rd_options ? \
252+
((StdRdOptions *) (relation)->rd_options)->parallel_degree : (defaultpd))
253+
245254

246255
/*
247256
* ViewOptions

0 commit comments

Comments
 (0)