aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2024-09-17 19:53:11 -0700
committerNoah Misch <noah@leadboat.com>2024-09-17 19:53:11 -0700
commitac04aa84a7f06635748278e6ff4bd74751bb3e8e (patch)
tree1e0a8281acf52b5b2c1e02070edc58d5346ccd22 /src
parent933848d16dc9d9d838c1bc15ed7e48c2f2eed69c (diff)
downloadpostgresql-ac04aa84a7f06635748278e6ff4bd74751bb3e8e.tar.gz
postgresql-ac04aa84a7f06635748278e6ff4bd74751bb3e8e.zip
Don't enter parallel mode when holding interrupts.
Doing so caused the leader to hang in wait_event=ParallelFinish, which required an immediate shutdown to resolve. Back-patch to v12 (all supported versions). Francesco Degrassi Discussion: https://postgr.es/m/CAC-SaSzHUKT=vZJ8MPxYdC_URPfax+yoA1hKTcF4ROz_Q6z0_Q@mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/plan/planner.c6
-rw-r--r--src/test/regress/expected/select_parallel.out24
-rw-r--r--src/test/regress/sql/select_parallel.sql31
3 files changed, 61 insertions, 0 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index df35d1ff9c4..d92d43a17ea 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -342,6 +342,11 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
* we want to allow parallel inserts in general; updates and deletes have
* additional problems especially around combo CIDs.)
*
+ * We don't try to use parallel mode unless interruptible. The leader
+ * expects ProcessInterrupts() calls to reach HandleParallelMessages().
+ * Even if we called HandleParallelMessages() another way, starting a
+ * parallel worker is too delay-prone to be prudent when uncancellable.
+ *
* For now, we don't try to use parallel mode if we're running inside a
* parallel worker. We might eventually be able to relax this
* restriction, but for now it seems best not to have parallel workers
@@ -352,6 +357,7 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
parse->commandType == CMD_SELECT &&
!parse->hasModifyingCTE &&
max_parallel_workers_per_gather > 0 &&
+ INTERRUPTS_CAN_BE_PROCESSED() &&
!IsParallelWorker())
{
/* all the cheap tests pass, so scan the query tree */
diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out
index c565407082c..2c63aa85a6e 100644
--- a/src/test/regress/expected/select_parallel.out
+++ b/src/test/regress/expected/select_parallel.out
@@ -1386,3 +1386,27 @@ reset debug_parallel_query;
drop function set_and_report_role();
drop function set_role_and_error(int);
drop role regress_parallel_worker;
+-- don't freeze in ParallelFinish while holding an LWLock
+BEGIN;
+CREATE FUNCTION my_cmp (int4, int4)
+RETURNS int LANGUAGE sql AS
+$$
+ SELECT
+ CASE WHEN $1 < $2 THEN -1
+ WHEN $1 > $2 THEN 1
+ ELSE 0
+ END;
+$$;
+CREATE TABLE parallel_hang (i int4);
+INSERT INTO parallel_hang
+ (SELECT * FROM generate_series(1, 400) gs);
+CREATE OPERATOR CLASS int4_custom_ops FOR TYPE int4 USING btree AS
+ OPERATOR 1 < (int4, int4), OPERATOR 2 <= (int4, int4),
+ OPERATOR 3 = (int4, int4), OPERATOR 4 >= (int4, int4),
+ OPERATOR 5 > (int4, int4), FUNCTION 1 my_cmp(int4, int4);
+CREATE UNIQUE INDEX parallel_hang_idx
+ ON parallel_hang
+ USING btree (i int4_custom_ops);
+SET debug_parallel_query = on;
+DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420;
+ROLLBACK;
diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql
index 22384b5ad85..9ba1328fd2e 100644
--- a/src/test/regress/sql/select_parallel.sql
+++ b/src/test/regress/sql/select_parallel.sql
@@ -543,3 +543,34 @@ reset debug_parallel_query;
drop function set_and_report_role();
drop function set_role_and_error(int);
drop role regress_parallel_worker;
+
+-- don't freeze in ParallelFinish while holding an LWLock
+BEGIN;
+
+CREATE FUNCTION my_cmp (int4, int4)
+RETURNS int LANGUAGE sql AS
+$$
+ SELECT
+ CASE WHEN $1 < $2 THEN -1
+ WHEN $1 > $2 THEN 1
+ ELSE 0
+ END;
+$$;
+
+CREATE TABLE parallel_hang (i int4);
+INSERT INTO parallel_hang
+ (SELECT * FROM generate_series(1, 400) gs);
+
+CREATE OPERATOR CLASS int4_custom_ops FOR TYPE int4 USING btree AS
+ OPERATOR 1 < (int4, int4), OPERATOR 2 <= (int4, int4),
+ OPERATOR 3 = (int4, int4), OPERATOR 4 >= (int4, int4),
+ OPERATOR 5 > (int4, int4), FUNCTION 1 my_cmp(int4, int4);
+
+CREATE UNIQUE INDEX parallel_hang_idx
+ ON parallel_hang
+ USING btree (i int4_custom_ops);
+
+SET debug_parallel_query = on;
+DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420;
+
+ROLLBACK;