v1-0000-v14-invalidate-pgxactoff-after-remove-pgproc.patch
application/octet-stream
Filename: v1-0000-v14-invalidate-pgxactoff-after-remove-pgproc.patch
Type: application/octet-stream
Part: 2
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v1-0000
| File | + | − |
|---|---|---|
| src/backend/commands/indexcmds.c | 1 | 0 |
| src/backend/commands/vacuum.c | 1 | 0 |
| src/backend/replication/logical/logical.c | 1 | 0 |
| src/backend/replication/slot.c | 1 | 0 |
| src/backend/storage/ipc/procarray.c | 4 | 0 |
| src/backend/storage/lmgr/proc.c | 4 | 0 |
| src/include/storage/proc.h | 6 | 0 |
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.