mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	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
This commit is contained in:
		@@ -333,6 +333,11 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
 | 
				
			|||||||
	 * if we want to allow parallel inserts in general; updates and deletes
 | 
						 * if we want to allow parallel inserts in general; updates and deletes
 | 
				
			||||||
	 * have additional problems especially around combo CIDs.)
 | 
						 * 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
 | 
						 * 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
 | 
						 * parallel worker.  We might eventually be able to relax this
 | 
				
			||||||
	 * restriction, but for now it seems best not to have parallel workers
 | 
						 * restriction, but for now it seems best not to have parallel workers
 | 
				
			||||||
@@ -343,6 +348,7 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
 | 
				
			|||||||
		parse->commandType == CMD_SELECT &&
 | 
							parse->commandType == CMD_SELECT &&
 | 
				
			||||||
		!parse->hasModifyingCTE &&
 | 
							!parse->hasModifyingCTE &&
 | 
				
			||||||
		max_parallel_workers_per_gather > 0 &&
 | 
							max_parallel_workers_per_gather > 0 &&
 | 
				
			||||||
 | 
							INTERRUPTS_CAN_BE_PROCESSED() &&
 | 
				
			||||||
		!IsParallelWorker())
 | 
							!IsParallelWorker())
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* all the cheap tests pass, so scan the query tree */
 | 
							/* all the cheap tests pass, so scan the query tree */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1252,3 +1252,27 @@ reset force_parallel_mode;
 | 
				
			|||||||
drop function set_and_report_role();
 | 
					drop function set_and_report_role();
 | 
				
			||||||
drop function set_role_and_error(int);
 | 
					drop function set_role_and_error(int);
 | 
				
			||||||
drop role regress_parallel_worker;
 | 
					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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -485,3 +485,34 @@ reset force_parallel_mode;
 | 
				
			|||||||
drop function set_and_report_role();
 | 
					drop function set_and_report_role();
 | 
				
			||||||
drop function set_role_and_error(int);
 | 
					drop function set_role_and_error(int);
 | 
				
			||||||
drop role regress_parallel_worker;
 | 
					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;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user