diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index e4c792228f..85d10ba338 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -4397,6 +4397,7 @@ set_indexsafe_procflags(void) LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); MyProc->statusFlags |= PROC_IN_SAFE_IC; + Assert(PGXactOffIsValid(MyProc->pgxactoff)); ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; LWLockRelease(ProcArrayLock); } diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 69ac276687..d4b095ed0e 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2011,6 +2011,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, MyProc->statusFlags |= PROC_IN_VACUUM; if (params->is_wraparound) MyProc->statusFlags |= PROC_VACUUM_FOR_WRAPAROUND; + Assert(PGXactOffIsValid(MyProc->pgxactoff)); ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; LWLockRelease(ProcArrayLock); } diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c index 41243d0187..1dd47e158a 100644 --- a/src/backend/replication/logical/logical.c +++ b/src/backend/replication/logical/logical.c @@ -195,6 +195,7 @@ StartupDecodingContext(List *output_plugin_options, { LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); MyProc->statusFlags |= PROC_IN_LOGICAL_DECODING; + Assert(PGXactOffIsValid(MyProc->pgxactoff)); ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; LWLockRelease(ProcArrayLock); } diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index e70f066eb8..c1a46df56d 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -593,6 +593,7 @@ ReplicationSlotRelease(void) /* might not have been set when we've been a plain slot */ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); MyProc->statusFlags &= ~PROC_IN_LOGICAL_DECODING; + Assert(PGXactOffIsValid(MyProc->pgxactoff)); ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; LWLockRelease(ProcArrayLock); } diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index e630302351..3ec2d19cd3 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -611,6 +611,7 @@ ProcArrayRemove(PGPROC *proc, TransactionId latestXid) Assert(ProcGlobal->subxidStates[myoff].overflowed == false); ProcGlobal->statusFlags[myoff] = 0; + proc->pgxactoff = InvalidPGXactOff; /* Keep the PGPROC array sorted. See notes above */ movecount = arrayP->numProcs - myoff - 1; @@ -718,6 +719,7 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid) Assert(!LWLockHeldByMe(ProcArrayLock)); LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); Assert(proc->statusFlags == ProcGlobal->statusFlags[proc->pgxactoff]); + Assert(PGXactOffIsValid(MyProc->pgxactoff)); proc->statusFlags &= ~PROC_VACUUM_STATE_MASK; ProcGlobal->statusFlags[proc->pgxactoff] = proc->statusFlags; LWLockRelease(ProcArrayLock); @@ -758,6 +760,7 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid) if (proc->statusFlags & PROC_VACUUM_STATE_MASK) { proc->statusFlags &= ~PROC_VACUUM_STATE_MASK; + Assert(PGXactOffIsValid(MyProc->pgxactoff)); ProcGlobal->statusFlags[proc->pgxactoff] = proc->statusFlags; } @@ -2655,6 +2658,7 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc) MyProc->xmin = TransactionXmin = xmin; MyProc->statusFlags = (MyProc->statusFlags & ~PROC_XMIN_FLAGS) | (proc->statusFlags & PROC_XMIN_FLAGS); + Assert(PGXactOffIsValid(MyProc->pgxactoff)); ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags; result = true; diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index e9e445bb21..2d33f43d50 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -192,6 +192,10 @@ InitProcGlobal(void) procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC)); MemSet(procs, 0, TotalProcs * sizeof(PGPROC)); ProcGlobal->allProcs = procs; + for (int index = 0; index < TotalProcs; index++) + { + procs[index].pgxactoff = InvalidPGXactOff; + } /* XXX allProcCount isn't really all of them; it excludes prepared xacts */ ProcGlobal->allProcCount = MaxBackends + NUM_AUXILIARY_PROCS; diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index ef74f32693..c137ce228d 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -132,6 +132,12 @@ typedef enum PROC_WAIT_STATUS_ERROR, } ProcWaitStatus; +/* + * Invalid value for PGPROC->pgxactoff. + */ +#define InvalidPGXactOff -1 +#define PGXactOffIsValid(pgxactoff) ((pgxactoff) != InvalidPGXactOff) + /* * Each backend has a PGPROC struct in shared memory. There is also a list of * currently-unused PGPROC structs that will be reallocated to new backends.