From 94b4f7e2a635c3027a23b07086f740615b56aa64 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 16 Oct 2015 09:59:57 -0400 Subject: [PATCH] Tighten up application of parallel mode checks. Commit 924bcf4f16d54c55310b28f77686608684734f42 failed to enforce parallel mode checks during the commit of a parallel worker, because we exited parallel mode prior to ending the transaction so that we could pop the active snapshot. Re-establish parallel mode during parallel worker commit. Without this, it's far too easy for unsafe actions during the pre-commit sequence to crash the server instead of hitting the error checks as intended. Just to be extra paranoid, adjust a couple of the sanity checks in xact.c to check not only IsInParallelMode() but also IsParallelWorker(). --- src/backend/access/transam/xact.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 3e24800fbd..47312f6854 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -497,7 +497,7 @@ AssignTransactionId(TransactionState s) * Workers synchronize transaction state at the beginning of each parallel * operation, so we can't account for new XIDs at this point. */ - if (IsInParallelMode()) + if (IsInParallelMode() || IsParallelWorker()) elog(ERROR, "cannot assign XIDs during a parallel operation"); /* @@ -931,7 +931,7 @@ CommandCounterIncrement(void) * parallel operation, so we can't account for new commands after that * point. */ - if (IsInParallelMode()) + if (IsInParallelMode() || IsParallelWorker()) elog(ERROR, "cannot start commands during a parallel operation"); currentCommandId += 1; @@ -1927,6 +1927,10 @@ CommitTransaction(void) is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS); + /* Enforce parallel mode restrictions during parallel worker commit. */ + if (is_parallel_worker) + EnterParallelMode(); + ShowTransactionState("CommitTransaction"); /* @@ -1971,10 +1975,7 @@ CommitTransaction(void) /* If we might have parallel workers, clean them up now. */ if (IsInParallelMode()) - { AtEOXact_Parallel(true); - s->parallelModeLevel = 0; - } /* Shut down the deferred-trigger manager */ AfterTriggerEndXact(true); @@ -2013,6 +2014,7 @@ CommitTransaction(void) * commit processing */ s->state = TRANS_COMMIT; + s->parallelModeLevel = 0; if (!is_parallel_worker) {