diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 05221cc1d6..5fbeacc0da 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -4147,6 +4147,12 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) LVRelState vacrel; ErrorContextCallback errcallback; + /* + * A parallel vacuum worker must have only PROC_IN_VACUUM flag since we + * don't support parallel vacuum for autovacuum as of now. + */ + Assert(MyProc->statusFlags == PROC_IN_VACUUM); + lvshared = (LVShared *) shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_SHARED, false); elevel = lvshared->elevel; diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index 54c8eb1289..af562fcfae 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -1808,6 +1808,13 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc) ResetUsage(); #endif /* BTREE_BUILD_STATS */ + /* + * A possible status flag that can be set to the parallel worker is + * only PROC_IN_SAFE_IC. + */ + Assert((MyProc->statusFlags == 0) || + (MyProc->statusFlags == PROC_IN_SAFE_IC)); + /* Set debug_query_string for individual workers first */ sharedquery = shm_toc_lookup(toc, PARALLEL_KEY_QUERY_TEXT, true); debug_query_string = sharedquery; diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index bd3c7a47fe..64fa2db471 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -2636,7 +2636,8 @@ ProcArrayInstallImportedXmin(TransactionId xmin, * * This is like ProcArrayInstallImportedXmin, but we have a pointer to the * PGPROC of the transaction from which we imported the snapshot, rather than - * an XID. + * an XID. Also, this copies statusFlags from source xact so as not to affect + * OldestXmin in case of parallel workers for vacuum etc. * * Returns true if successful, false if source xact is no longer running. */ @@ -2645,6 +2646,7 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc) { bool result = false; TransactionId xid; + uint8 flags; Assert(TransactionIdIsNormal(xmin)); Assert(proc != NULL); @@ -2652,6 +2654,18 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc) /* Get lock so source xact can't end while we're doing this */ LWLockAcquire(ProcArrayLock, LW_SHARED); + flags = proc->statusFlags; + + /* + * If the source xact has any statusFlags, we re-grab ProcArrayLock + * on exclusive mode so we can copy it to MyProc->statusFlags. + */ + if (flags != 0) + { + LWLockRelease(ProcArrayLock); + LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); + } + /* * Be certain that the referenced PGPROC has an advertised xmin which is * no later than the one we're installing, so that the system-wide xmin @@ -2663,7 +2677,16 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc) TransactionIdIsNormal(xid) && TransactionIdPrecedesOrEquals(xid, xmin)) { + /* restore xmin */ MyProc->xmin = TransactionXmin = xmin; + + /* copy statusFlags */ + if (flags != 0) + { + MyProc->statusFlags = proc->statusFlags; + ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; + } + result = true; }