From dc0577899642da7847e25673bac2ab3b526bdb62 Mon Sep 17 00:00:00 2001 From: houzj Date: Fri, 29 Jan 2021 13:19:41 +0800 Subject: [PATCH 1/2] reloption parallel_dml src add new tableoption parallel_dml In addition to guc option, user may want to use parallel dml for some specific tables.So add new tableoption parallel_dml, let user decide whether to use parallel DML for specific table. The default is false. --- src/backend/access/common/reloptions.c | 25 +++++++++++++++++++++---- src/backend/optimizer/util/clauses.c | 26 ++++++++++++++++++++++++++ src/bin/psql/tab-complete.c | 1 + src/include/utils/rel.h | 10 ++++++++++ 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index c687d3e..f30f2fa 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -168,6 +168,15 @@ static relopt_bool boolRelOpts[] = }, true }, + { + { + "parallel_dml", + "Enables \"parallel dml\" feature for this table", + RELOPT_KIND_HEAP | RELOPT_KIND_PARTITIONED, + ShareUpdateExclusiveLock + }, + false + }, /* list terminator */ {{NULL}} }; @@ -1859,7 +1868,9 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind) {"vacuum_index_cleanup", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, vacuum_index_cleanup)}, {"vacuum_truncate", RELOPT_TYPE_BOOL, - offsetof(StdRdOptions, vacuum_truncate)} + offsetof(StdRdOptions, vacuum_truncate)}, + {"parallel_dml", RELOPT_TYPE_BOOL, + offsetof(StdRdOptions, parallel_dml)} }; return (bytea *) build_reloptions(reloptions, validate, kind, @@ -1961,13 +1972,19 @@ build_local_reloptions(local_relopts *relopts, Datum options, bool validate) bytea * partitioned_table_reloptions(Datum reloptions, bool validate) { + static const relopt_parse_elt tab[] = { + {"parallel_dml", RELOPT_TYPE_BOOL, + offsetof(StdRdOptions, parallel_dml)} + }; + /* - * There are no options for partitioned tables yet, but this is able to do - * some validation. + * The only option for partitioned tables works for heap too, + * so we temporarily store it in the same struct as heap. */ return (bytea *) build_reloptions(reloptions, validate, RELOPT_KIND_PARTITIONED, - 0, NULL, 0); + sizeof(StdRdOptions), + tab, lengthof(tab)); } /* diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 02a7e05..9d4b100 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -570,6 +570,32 @@ max_parallel_hazard(Query *parse) context.max_hazard = PROPARALLEL_SAFE; context.max_interesting = PROPARALLEL_UNSAFE; context.safe_param_ids = NIL; + + if (IsModifySupportedInParallelMode(parse->commandType)) + { + Relation rel; + RangeTblEntry *rte; + + rte = rt_fetch(parse->resultRelation, parse->rtable); + rel = table_open(rte->relid, NoLock); + + /* + * Check if parallel_dml is enabled for the target table, + * if not, skip the safety checks and return PARALLEL_UNSAFE. + * + * (Note: if target table is partitioned, we just check the + * option of parent table and ignore the option values for its child) + */ + if(!RelationGetParallelDML(rel, false)) + { + table_close(rel, NoLock); + return PROPARALLEL_UNSAFE; + } + + table_close(rel, NoLock); + } + + (void) max_parallel_hazard_walker((Node *) parse, &context); /* diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 17f7265..38f5b1e 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -1110,6 +1110,7 @@ static const char *const table_storage_parameters[] = { "autovacuum_vacuum_threshold", "fillfactor", "log_autovacuum_min_duration", + "parallel_dml", "parallel_workers", "toast.autovacuum_enabled", "toast.autovacuum_freeze_max_age", diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 2a41a00..9dc1ab8 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -307,6 +307,7 @@ typedef struct StdRdOptions int parallel_workers; /* max number of parallel workers */ bool vacuum_index_cleanup; /* enables index vacuuming and cleanup */ bool vacuum_truncate; /* enables vacuum to truncate a relation */ + bool parallel_dml; /* enable parallel table-modification */ } StdRdOptions; #define HEAP_MIN_FILLFACTOR 10 @@ -362,6 +363,15 @@ typedef struct StdRdOptions ((relation)->rd_options ? \ ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw)) +/* + * RelationGetParallelDML + * Returns the relation's parallel_dml reloption setting. + * Note multiple eval of argument! + */ +#define RelationGetParallelDML(relation, defaultpd) \ + ((relation)->rd_options ? \ + ((StdRdOptions *) (relation)->rd_options)->parallel_dml : (defaultpd)) + /* ViewOptions->check_option values */ typedef enum ViewOptCheckOption { -- 2.7.2.windows.1