@@ -222,7 +222,7 @@ static void XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len);
222222static char * ProcessTwoPhaseBuffer (TransactionId xid ,
223223 XLogRecPtr prepare_start_lsn ,
224224 bool fromdisk , bool overwriteOK , bool setParent ,
225- TransactionId * result , TransactionId * maxsubxid );
225+ bool setNextXid );
226226static void MarkAsPreparingGuts (GlobalTransaction gxact , TransactionId xid ,
227227 const char * gid , TimestampTz prepared_at , Oid owner ,
228228 Oid databaseid );
@@ -1744,7 +1744,7 @@ restoreTwoPhaseData(void)
17441744
17451745 buf = ProcessTwoPhaseBuffer (xid , InvalidXLogRecPtr ,
17461746 true, false, false,
1747- NULL , NULL );
1747+ false );
17481748 if (buf == NULL )
17491749 continue ;
17501750
@@ -1786,7 +1786,6 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
17861786{
17871787 TransactionId origNextXid = ShmemVariableCache -> nextXid ;
17881788 TransactionId result = origNextXid ;
1789- TransactionId maxsubxid = origNextXid ;
17901789 TransactionId * xids = NULL ;
17911790 int nxids = 0 ;
17921791 int allocsize = 0 ;
@@ -1806,11 +1805,18 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
18061805 buf = ProcessTwoPhaseBuffer (xid ,
18071806 gxact -> prepare_start_lsn ,
18081807 gxact -> ondisk , false, false,
1809- & result , & maxsubxid );
1808+ true );
18101809
18111810 if (buf == NULL )
18121811 continue ;
18131812
1813+ /*
1814+ * OK, we think this file is valid. Incorporate xid into the
1815+ * running-minimum result.
1816+ */
1817+ if (TransactionIdPrecedes (xid , result ))
1818+ result = xid ;
1819+
18141820 if (xids_p )
18151821 {
18161822 if (nxids == allocsize )
@@ -1839,15 +1845,6 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
18391845 * nxids_p = nxids ;
18401846 }
18411847
1842- /* update nextXid if needed */
1843- if (TransactionIdFollowsOrEquals (maxsubxid , ShmemVariableCache -> nextXid ))
1844- {
1845- LWLockAcquire (XidGenLock , LW_EXCLUSIVE );
1846- ShmemVariableCache -> nextXid = maxsubxid ;
1847- TransactionIdAdvance (ShmemVariableCache -> nextXid );
1848- LWLockRelease (XidGenLock );
1849- }
1850-
18511848 return result ;
18521849}
18531850
@@ -1884,7 +1881,7 @@ StandbyRecoverPreparedTransactions(bool overwriteOK)
18841881 buf = ProcessTwoPhaseBuffer (xid ,
18851882 gxact -> prepare_start_lsn ,
18861883 gxact -> ondisk , overwriteOK , true,
1887- NULL , NULL );
1884+ false );
18881885 if (buf != NULL )
18891886 pfree (buf );
18901887 }
@@ -1924,7 +1921,7 @@ RecoverPreparedTransactions(void)
19241921 buf = ProcessTwoPhaseBuffer (xid ,
19251922 gxact -> prepare_start_lsn ,
19261923 gxact -> ondisk , false, false,
1927- NULL , NULL );
1924+ false );
19281925 if (buf == NULL )
19291926 continue ;
19301927
@@ -2012,20 +2009,16 @@ RecoverPreparedTransactions(void)
20122009 * If setParent is true, then use the overwriteOK parameter to set up
20132010 * subtransaction parent linkages.
20142011 *
2015- * If result and maxsubxid are not NULL, fill them up with smallest
2016- * running transaction id (lesser than ShmemVariableCache->nextXid)
2017- * and largest subtransaction id for this transaction respectively.
2012+ * If setNextXid is true, set ShmemVariableCache->nextXid to the newest
2013+ * value scanned.
20182014 */
20192015static char *
20202016ProcessTwoPhaseBuffer (TransactionId xid ,
20212017 XLogRecPtr prepare_start_lsn ,
20222018 bool fromdisk , bool overwriteOK ,
2023- bool setParent , TransactionId * result ,
2024- TransactionId * maxsubxid )
2019+ bool setParent , bool setNextXid )
20252020{
20262021 TransactionId origNextXid = ShmemVariableCache -> nextXid ;
2027- TransactionId res = InvalidTransactionId ;
2028- TransactionId maxsub = InvalidTransactionId ;
20292022 TransactionId * subxids ;
20302023 char * buf ;
20312024 TwoPhaseFileHeader * hdr ;
@@ -2034,11 +2027,6 @@ ProcessTwoPhaseBuffer(TransactionId xid,
20342027 if (!fromdisk )
20352028 Assert (prepare_start_lsn != InvalidXLogRecPtr );
20362029
2037- if (result )
2038- res = * result ;
2039- if (maxsubxid )
2040- maxsub = * maxsubxid ;
2041-
20422030 /* Already processed? */
20432031 if (TransactionIdDidCommit (xid ) || TransactionIdDidAbort (xid ))
20442032 {
@@ -2120,13 +2108,6 @@ ProcessTwoPhaseBuffer(TransactionId xid,
21202108 return NULL ;
21212109 }
21222110
2123- /*
2124- * OK, we think this buffer is valid. Incorporate xid into the
2125- * running-minimum result.
2126- */
2127- if (TransactionIdPrecedes (xid , res ))
2128- res = xid ;
2129-
21302111 /*
21312112 * Examine subtransaction XIDs ... they should all follow main
21322113 * XID, and they may force us to advance nextXid.
@@ -2139,17 +2120,31 @@ ProcessTwoPhaseBuffer(TransactionId xid,
21392120 TransactionId subxid = subxids [i ];
21402121
21412122 Assert (TransactionIdFollows (subxid , xid ));
2142- if (TransactionIdFollowsOrEquals (subxid , maxsub ))
2143- maxsub = subxid ;
2123+
2124+ /* update nextXid if needed */
2125+ if (setNextXid &&
2126+ TransactionIdFollowsOrEquals (subxid ,
2127+ ShmemVariableCache -> nextXid ))
2128+ {
2129+ /*
2130+ * We don't expect anyone else to modify nextXid, hence we don't
2131+ * need to hold a lock while examining it. We still acquire the
2132+ * lock to modify it, though, so we recheck.
2133+ */
2134+ LWLockAcquire (XidGenLock , LW_EXCLUSIVE );
2135+ if (TransactionIdFollowsOrEquals (subxid ,
2136+ ShmemVariableCache -> nextXid ))
2137+ {
2138+ ShmemVariableCache -> nextXid = subxid ;
2139+ TransactionIdAdvance (ShmemVariableCache -> nextXid );
2140+ }
2141+ LWLockRelease (XidGenLock );
2142+ }
2143+
21442144 if (setParent )
21452145 SubTransSetParent (xid , subxid , overwriteOK );
21462146 }
21472147
2148- if (result )
2149- * result = res ;
2150- if (maxsubxid )
2151- * maxsubxid = maxsub ;
2152-
21532148 return buf ;
21542149}
21552150
0 commit comments