diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index f357804fda0..4164fcc5542 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -219,6 +219,15 @@ InitializeParallelDSM(ParallelContext *pcxt) shm_toc_estimate_chunk(&pcxt->estimator, sizeof(FixedParallelState)); shm_toc_estimate_keys(&pcxt->estimator, 1); + /* + * If we manage to reach here while non-interruptible, it's unsafe to + * launch any workers: we would fail to process interrupts sent by them. + * We can deal with that edge case by pretending no workers were + * requested. + */ + if (!INTERRUPTS_CAN_BE_PROCESSED()) + pcxt->nworkers = 0; + /* * Normally, the user will have requested at least one worker process, but * if by chance they have not, we can skip a bunch of things here. diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index 5808ef48900..b4b711e6c4e 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -1516,8 +1516,13 @@ void ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *cxt) { int plan_node_id = state->js.ps.plan->plan_node_id; - ParallelHashJoinState *pstate = - shm_toc_lookup(cxt->toc, plan_node_id, false); + ParallelHashJoinState *pstate; + + /* Nothing to do if we failed to create a DSM segment. */ + if (cxt->seg == NULL) + return; + + pstate = shm_toc_lookup(cxt->toc, plan_node_id, false); /* * It would be possible to reuse the shared hash table in single-batch diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 0c058d0e7d9..6428caa83b4 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -331,11 +331,6 @@ 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 @@ -346,7 +341,6 @@ 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 */