diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index fe2a6062b9c..e1bb97951b0 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -3482,6 +3482,12 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) LVRelStats vacrelstats; 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(MyPgXact->vacuumFlags == PROC_IN_VACUUM); + lvshared = (LVShared *) shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_SHARED, false); elevel = lvshared->elevel; diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 828ed2a38a1..2f1d4af17a5 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -1864,6 +1864,10 @@ ProcArrayInstallImportedXmin(TransactionId xmin, * PGPROC of the transaction from which we imported the snapshot, rather than * an XID. * + * Note that this function also copies vacuumFlags from the source `proc` in + * order to avoid the case where MyPgXact's xmin needs to be skipped for + * computing xid horizon. + * * Returns true if successful, false if source xact is no longer running. */ bool @@ -1876,8 +1880,10 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc) Assert(TransactionIdIsNormal(xmin)); Assert(proc != NULL); - /* Get lock so source xact can't end while we're doing this */ - LWLockAcquire(ProcArrayLock, LW_SHARED); + /* + * Get an exclusive lock so that we can copy vacuumFlags from source proc. + */ + LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); pgxact = &allPgXact[proc->pgprocno]; @@ -1892,7 +1898,13 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc) TransactionIdIsNormal(xid) && TransactionIdPrecedesOrEquals(xid, xmin)) { + /* Install xmin */ MyPgXact->xmin = TransactionXmin = xmin; + + /* Flags being copied must be valid copy-able flags. */ + Assert((pgxact->vacuumFlags & (~PROC_COPYABLE_FLAGS)) == 0); + MyPgXact->vacuumFlags = pgxact->vacuumFlags; + result = true; } diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index 1ee9000b2b9..b3ea1a25860 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -62,6 +62,13 @@ struct XidCache #define PROC_VACUUM_STATE_MASK \ (PROC_IN_VACUUM | PROC_IN_ANALYZE | PROC_VACUUM_FOR_WRAPAROUND) +/* + * Flags that are valid to copy from another proc, the parallel leader + * process in practice. Currently, a flag that is set during parallel + * vacuum is allowed. + */ +#define PROC_COPYABLE_FLAGS (PROC_IN_VACUUM) + /* * We allow a small number of "weak" relation locks (AccessShareLock, * RowShareLock, RowExclusiveLock) to be recorded in the PGPROC structure