aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc/procarray.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/ipc/procarray.c')
-rw-r--r--src/backend/storage/ipc/procarray.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 8bda474bc71..09b7311e7bc 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -654,17 +654,28 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
running->latestCompletedXid))
ShmemVariableCache->latestCompletedXid = running->latestCompletedXid;
- /* nextXid must be beyond any observed xid */
+ Assert(TransactionIdIsNormal(ShmemVariableCache->latestCompletedXid));
+
+ LWLockRelease(ProcArrayLock);
+
+ /*
+ * ShmemVariableCache->nextXid must be beyond any observed xid.
+ *
+ * We don't expect anyone else to modify nextXid, hence we don't need to
+ * hold a lock while examining it. We still acquire the lock to modify
+ * it, though.
+ */
nextXid = latestObservedXid;
TransactionIdAdvance(nextXid);
if (TransactionIdFollows(nextXid, ShmemVariableCache->nextXid))
+ {
+ LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
ShmemVariableCache->nextXid = nextXid;
+ LWLockRelease(XidGenLock);
+ }
- Assert(TransactionIdIsNormal(ShmemVariableCache->latestCompletedXid));
Assert(TransactionIdIsValid(ShmemVariableCache->nextXid));
- LWLockRelease(ProcArrayLock);
-
KnownAssignedXidsDisplay(trace_recovery(DEBUG3));
if (standbyState == STANDBY_SNAPSHOT_READY)
elog(trace_recovery(DEBUG1), "recovery snapshots are now enabled");
@@ -1690,6 +1701,13 @@ GetOldestActiveTransactionId(void)
LWLockAcquire(ProcArrayLock, LW_SHARED);
+ /*
+ * It's okay to read nextXid without acquiring XidGenLock because (1) we
+ * assume TransactionIds can be read atomically and (2) we don't care if
+ * we get a slightly stale value. It can't be very stale anyway, because
+ * the LWLockAcquire above will have done any necessary memory
+ * interlocking.
+ */
oldestRunningXid = ShmemVariableCache->nextXid;
/*
@@ -2609,7 +2627,9 @@ RecordKnownAssignedTransactionIds(TransactionId xid)
/* ShmemVariableCache->nextXid must be beyond any observed xid */
next_expected_xid = latestObservedXid;
TransactionIdAdvance(next_expected_xid);
+ LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
ShmemVariableCache->nextXid = next_expected_xid;
+ LWLockRelease(XidGenLock);
}
}