Skip to content

Commit 06424e9

Browse files
committed
Improve fix for not entering parallel mode when holding interrupts.
Commit ac04aa8 put the shutoff for this into the planner, which is not ideal because it doesn't prevent us from re-using a previously made parallel plan. Revert the planner change and instead put the shutoff into InitializeParallelDSM, modeling it on the existing code there for recovering from failure to allocate a DSM segment. However, that code path is mostly untested, and testing a bit harder showed there's at least one bug: ExecHashJoinReInitializeDSM is not prepared for us to have skipped doing parallel DSM setup. I also thought the Assert in ReinitializeParallelWorkers is pretty ill-advised, and replaced it with a silent Min() operation. The existing test case added by ac04aa8 serves fine to test this version of the fix, so no change needed there. Patch by me, but thanks to Noah Misch for the core idea that we could shut off worker creation when !INTERRUPTS_CAN_BE_PROCESSED. Back-patch to v12, as ac04aa8 was. Discussion: https://postgr.es/m/CAC-SaSzHUKT=vZJ8MPxYdC_URPfax+yoA1hKTcF4ROz_Q6z0_Q@mail.gmail.com
1 parent f734b6b commit 06424e9

File tree

3 files changed

+23
-11
lines changed

3 files changed

+23
-11
lines changed

src/backend/access/transam/parallel.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,15 @@ InitializeParallelDSM(ParallelContext *pcxt)
228228
shm_toc_estimate_chunk(&pcxt->estimator, sizeof(FixedParallelState));
229229
shm_toc_estimate_keys(&pcxt->estimator, 1);
230230

231+
/*
232+
* If we manage to reach here while non-interruptible, it's unsafe to
233+
* launch any workers: we would fail to process interrupts sent by them.
234+
* We can deal with that edge case by pretending no workers were
235+
* requested.
236+
*/
237+
if (!INTERRUPTS_CAN_BE_PROCESSED())
238+
pcxt->nworkers = 0;
239+
231240
/*
232241
* Normally, the user will have requested at least one worker process, but
233242
* if by chance they have not, we can skip a bunch of things here.
@@ -474,6 +483,9 @@ InitializeParallelDSM(ParallelContext *pcxt)
474483
shm_toc_insert(pcxt->toc, PARALLEL_KEY_ENTRYPOINT, entrypointstate);
475484
}
476485

486+
/* Update nworkers_to_launch, in case we changed nworkers above. */
487+
pcxt->nworkers_to_launch = pcxt->nworkers;
488+
477489
/* Restore previous memory context. */
478490
MemoryContextSwitchTo(oldcontext);
479491
}
@@ -537,10 +549,11 @@ ReinitializeParallelWorkers(ParallelContext *pcxt, int nworkers_to_launch)
537549
{
538550
/*
539551
* The number of workers that need to be launched must be less than the
540-
* number of workers with which the parallel context is initialized.
552+
* number of workers with which the parallel context is initialized. But
553+
* the caller might not know that InitializeParallelDSM reduced nworkers,
554+
* so just silently trim the request.
541555
*/
542-
Assert(pcxt->nworkers >= nworkers_to_launch);
543-
pcxt->nworkers_to_launch = nworkers_to_launch;
556+
pcxt->nworkers_to_launch = Min(pcxt->nworkers, nworkers_to_launch);
544557
}
545558

546559
/*

src/backend/executor/nodeHashjoin.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1622,8 +1622,13 @@ void
16221622
ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *pcxt)
16231623
{
16241624
int plan_node_id = state->js.ps.plan->plan_node_id;
1625-
ParallelHashJoinState *pstate =
1626-
shm_toc_lookup(pcxt->toc, plan_node_id, false);
1625+
ParallelHashJoinState *pstate;
1626+
1627+
/* Nothing to do if we failed to create a DSM segment. */
1628+
if (pcxt->seg == NULL)
1629+
return;
1630+
1631+
pstate = shm_toc_lookup(pcxt->toc, plan_node_id, false);
16271632

16281633
/*
16291634
* It would be possible to reuse the shared hash table in single-batch

src/backend/optimizer/plan/planner.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,6 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
338338
* if we want to allow parallel inserts in general; updates and deletes
339339
* have additional problems especially around combo CIDs.)
340340
*
341-
* We don't try to use parallel mode unless interruptible. The leader
342-
* expects ProcessInterrupts() calls to reach HandleParallelMessages().
343-
* Even if we called HandleParallelMessages() another way, starting a
344-
* parallel worker is too delay-prone to be prudent when uncancellable.
345-
*
346341
* For now, we don't try to use parallel mode if we're running inside a
347342
* parallel worker. We might eventually be able to relax this
348343
* restriction, but for now it seems best not to have parallel workers
@@ -353,7 +348,6 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
353348
parse->commandType == CMD_SELECT &&
354349
!parse->hasModifyingCTE &&
355350
max_parallel_workers_per_gather > 0 &&
356-
INTERRUPTS_CAN_BE_PROCESSED() &&
357351
!IsParallelWorker())
358352
{
359353
/* all the cheap tests pass, so scan the query tree */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy