Reorder actions in ProcArrayApplyRecoveryInfo()
authorAlexander Korotkov <[email protected]>
Fri, 19 Jan 2024 15:19:17 +0000 (17:19 +0200)
committerAlexander Korotkov <[email protected]>
Fri, 19 Jan 2024 15:19:17 +0000 (17:19 +0200)
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

index e2f71da4a016e013694f01bfee98cdcf523913fa..93cdc97166c53c2303ff6a1a4e7000c036b0afc3 100644 (file)
@@ -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");