From 5330f1df94b1549cef7de1a4d9be2b88a7d2866b Mon Sep 17 00:00:00 2001
From: houzj <houzj.fnst@cn.fujitsu.com>
Date: Thu, 18 Feb 2021 10:02:06 +0800
Subject: [PATCH 1/4] Add new GUC option: enable_parallel_dml (boolean)

The current implementation of parallel "INSERT ... SELECT ..." may incur
non-negligible overhead in the additional parallel-safety checks that it
performs, even when, in the end, those checks determine that parallelism
can't be used. This is normally only ever a problem for large complex tables,
particularly in the case of when the target table has a large number of
partitions.

To address this potential isse, a new GUC option "enable_parallel_dml" is
added, to allow parallel DML to be enabled/disabled.

The default is false.
---
 src/backend/optimizer/path/costsize.c         |  2 ++
 src/backend/optimizer/util/clauses.c          |  8 ++++++--
 src/backend/utils/misc/guc.c                  | 11 +++++++++++
 src/backend/utils/misc/postgresql.conf.sample |  1 +
 src/include/optimizer/cost.h                  |  1 +
 5 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index f7c13be..778f71b 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -129,6 +129,8 @@ Cost		disable_cost = 1.0e10;
 
 int			max_parallel_workers_per_gather = 2;
 
+bool		enable_parallel_dml = false;
+
 bool		enable_seqscan = true;
 bool		enable_indexscan = true;
 bool		enable_indexonlyscan = true;
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index de16a28..eb6eee5 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1219,8 +1219,9 @@ target_rel_max_parallel_hazard_recurse(Relation rel,
  * table-modification statement.
  * It's not possible in the following cases:
  *
- *  1) INSERT...ON CONFLICT...DO UPDATE
- *  2) INSERT without SELECT
+ *  1) enable_parallel_dml is off
+ *  2) INSERT...ON CONFLICT...DO UPDATE
+ *  3) INSERT without SELECT
  *
  * (Note: we don't do in-depth parallel-safety checks here, we do only the
  * cheaper tests that can quickly exclude obvious cases for which
@@ -1236,6 +1237,9 @@ is_parallel_possible_for_modify(Query *parse)
 
 	Assert(IsModifySupportedInParallelMode(parse->commandType));
 
+	if (!enable_parallel_dml)
+		return false;
+
 	/*
 	 * UPDATE is not currently supported in parallel-mode, so prohibit
 	 * INSERT...ON CONFLICT...DO UPDATE...
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index eafdb11..6fdb991 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2048,6 +2048,17 @@ static struct config_bool ConfigureNamesBool[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"enable_parallel_dml", PGC_USERSET, QUERY_TUNING_METHOD,
+			gettext_noop("Enables the planner's use of parallel plans for table-modification commands."),
+			NULL,
+			GUC_EXPLAIN
+		},
+		&enable_parallel_dml,
+		false,
+		NULL, NULL, NULL
+	},
+
 	/* End-of-list marker */
 	{
 		{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index db6db37..fdd1fce 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -370,6 +370,7 @@
 #enable_partitionwise_aggregate = off
 #enable_parallel_hash = on
 #enable_partition_pruning = on
+#enable_parallel_dml = off
 
 # - Planner Cost Constants -
 
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index 9f15fcb..4af0beb 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -47,6 +47,7 @@ typedef enum
 /* parameter variables and flags (see also optimizer.h) */
 extern PGDLLIMPORT Cost disable_cost;
 extern PGDLLIMPORT int max_parallel_workers_per_gather;
+extern PGDLLIMPORT bool enable_parallel_dml;
 extern PGDLLIMPORT bool enable_seqscan;
 extern PGDLLIMPORT bool enable_indexscan;
 extern PGDLLIMPORT bool enable_indexonlyscan;
-- 
2.7.2.windows.1

