diff options
Diffstat (limited to 'src/backend/storage/ipc/procarray.c')
-rw-r--r-- | src/backend/storage/ipc/procarray.c | 28 |
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); } } |