diff options
author | Noah Misch <noah@leadboat.com> | 2024-09-17 19:53:11 -0700 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2024-09-17 19:53:11 -0700 |
commit | ac04aa84a7f06635748278e6ff4bd74751bb3e8e (patch) | |
tree | 1e0a8281acf52b5b2c1e02070edc58d5346ccd22 /src | |
parent | 933848d16dc9d9d838c1bc15ed7e48c2f2eed69c (diff) | |
download | postgresql-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.c | 6 | ||||
-rw-r--r-- | src/test/regress/expected/select_parallel.out | 24 | ||||
-rw-r--r-- | src/test/regress/sql/select_parallel.sql | 31 |
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; |