From c64086b79dbad19e4ee0af8d19e835111aa87bd5 Mon Sep 17 00:00:00 2001 From: Alexander Korotkov Date: Fri, 19 Jan 2024 17:19:17 +0200 Subject: [PATCH] Reorder actions in ProcArrayApplyRecoveryInfo() Since 5a1dfde8334b, 2PC filenames use FullTransactionId. Thus, it needs to convert TransactionId to FullTransactionId in StandbyTransactionIdIsPrepared() using TransamVariables->nextXid. However, ProcArrayApplyRecoveryInfo() first releases locks with usage StandbyTransactionIdIsPrepared(), then advances TransamVariables->nextXid. This sequence of actions could cause errors. This commit makes ProcArrayApplyRecoveryInfo() advance TransamVariables->nextXid before releasing locks. Reported-by: Thomas Munro, Michael Paquier Discussion: https://postgr.es/m/CA%2BhUKGLj_ve1_pNAnxwYU9rDcv7GOhsYXJt7jMKSA%3D5-6ss-Cw%40mail.gmail.com Discussion: https://postgr.es/m/Zadp9f4E1MYvMJqe%40paquier.xyz --- src/backend/storage/ipc/procarray.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index e2f71da4a0..93cdc97166 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -1053,6 +1053,7 @@ void ProcArrayApplyRecoveryInfo(RunningTransactions running) { TransactionId *xids; + TransactionId xid; int nxids; int i; @@ -1066,6 +1067,16 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) */ ExpireOldKnownAssignedTransactionIds(running->oldestRunningXid); + /* + * Adjust TransamVariables->nextXid before StandbyReleaseOldLocks(), + * because we will need it up to date for accessing two-phase transactions + * in StandbyReleaseOldLocks(). + */ + xid = running->nextXid; + TransactionIdRetreat(xid); + AdvanceNextFullTransactionIdPastXid(xid); + Assert(FullTransactionIdIsValid(TransamVariables->nextXid)); + /* * Remove stale locks, if any. */ @@ -1275,11 +1286,6 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) LWLockRelease(ProcArrayLock); - /* TransamVariables->nextXid must be beyond any observed xid. */ - AdvanceNextFullTransactionIdPastXid(latestObservedXid); - - Assert(FullTransactionIdIsValid(TransamVariables->nextXid)); - KnownAssignedXidsDisplay(DEBUG3); if (standbyState == STANDBY_SNAPSHOT_READY) elog(DEBUG1, "recovery snapshots are now enabled");