]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Don't enter parallel mode when holding interrupts.
authorNoah Misch <noah@leadboat.com>
Wed, 18 Sep 2024 02:53:11 +0000 (19:53 -0700)
committerNoah Misch <noah@leadboat.com>
Wed, 18 Sep 2024 02:54:26 +0000 (19:54 -0700)
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

src/backend/optimizer/plan/planner.c
src/test/regress/expected/select_parallel.out
src/test/regress/sql/select_parallel.sql

index 65a9b0d802ac3a5c8ee403e47668cd088b5afe67..f7539fed6fb0dc61aa7b1b7a28d30baada9a4cf9 100644 (file)
@@ -331,6 +331,11 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
         * 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
@@ -341,6 +346,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
                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 */
index c5943e55a0eb332be497d02238032ec0a617cd4c..7df008c3c3f13d471687512ee0abae5f390ac283 100644 (file)
@@ -1207,3 +1207,27 @@ reset force_parallel_mode;
 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 force_parallel_mode = on;
+DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420;
+ROLLBACK;
index a31770cfc34e410c183709b70c0dd28c4bdaba00..2f7f7563d21ba7f2d763f1b751ede0716b108f0d 100644 (file)
@@ -477,3 +477,34 @@ reset force_parallel_mode;
 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 force_parallel_mode = on;
+DELETE FROM parallel_hang WHERE 380 <= i AND i <= 420;
+
+ROLLBACK;