@@ -222,7 +222,7 @@ static void XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len);
222222static char * ProcessTwoPhaseBuffer (TransactionId xid ,
223223XLogRecPtr prepare_start_lsn ,
224224bool fromdisk ,bool overwriteOK ,bool setParent ,
225- TransactionId * result , TransactionId * maxsubxid );
225+ bool setNextXid );
226226static void MarkAsPreparingGuts (GlobalTransaction gxact ,TransactionId xid ,
227227const char * gid ,TimestampTz prepared_at ,Oid owner ,
228228Oid databaseid );
@@ -1744,7 +1744,7 @@ restoreTwoPhaseData(void)
17441744
17451745buf = ProcessTwoPhaseBuffer (xid ,InvalidXLogRecPtr ,
17461746true, false, false,
1747- NULL , NULL );
1747+ false );
17481748if (buf == NULL )
17491749continue ;
17501750
@@ -1786,7 +1786,6 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
17861786{
17871787TransactionId origNextXid = ShmemVariableCache -> nextXid ;
17881788TransactionId result = origNextXid ;
1789- TransactionId maxsubxid = origNextXid ;
17901789TransactionId * xids = NULL ;
17911790int nxids = 0 ;
17921791int allocsize = 0 ;
@@ -1806,11 +1805,18 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
18061805buf = ProcessTwoPhaseBuffer (xid ,
18071806gxact -> prepare_start_lsn ,
18081807gxact -> ondisk , false, false,
1809- & result , & maxsubxid );
1808+ true );
18101809
18111810if (buf == NULL )
18121811continue ;
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+
18141820if (xids_p )
18151821{
18161822if (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-
18511848return result ;
18521849}
18531850
@@ -1884,7 +1881,7 @@ StandbyRecoverPreparedTransactions(bool overwriteOK)
18841881buf = ProcessTwoPhaseBuffer (xid ,
18851882gxact -> prepare_start_lsn ,
18861883gxact -> ondisk ,overwriteOK , true,
1887- NULL , NULL );
1884+ false );
18881885if (buf != NULL )
18891886pfree (buf );
18901887}
@@ -1924,7 +1921,7 @@ RecoverPreparedTransactions(void)
19241921buf = ProcessTwoPhaseBuffer (xid ,
19251922gxact -> prepare_start_lsn ,
19261923gxact -> ondisk , false, false,
1927- NULL , NULL );
1924+ false );
19281925if (buf == NULL )
19291926continue ;
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 ,
20212017XLogRecPtr prepare_start_lsn ,
20222018bool fromdisk ,bool overwriteOK ,
2023- bool setParent ,TransactionId * result ,
2024- TransactionId * maxsubxid )
2019+ bool setParent ,bool setNextXid )
20252020{
20262021TransactionId origNextXid = ShmemVariableCache -> nextXid ;
2027- TransactionId res = InvalidTransactionId ;
2028- TransactionId maxsub = InvalidTransactionId ;
20292022TransactionId * subxids ;
20302023char * buf ;
20312024TwoPhaseFileHeader * hdr ;
@@ -2034,11 +2027,6 @@ ProcessTwoPhaseBuffer(TransactionId xid,
20342027if (!fromdisk )
20352028Assert (prepare_start_lsn != InvalidXLogRecPtr );
20362029
2037- if (result )
2038- res = * result ;
2039- if (maxsubxid )
2040- maxsub = * maxsubxid ;
2041-
20422030/* Already processed? */
20432031if (TransactionIdDidCommit (xid )|| TransactionIdDidAbort (xid ))
20442032{
@@ -2120,13 +2108,6 @@ ProcessTwoPhaseBuffer(TransactionId xid,
21202108return 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,
21392120TransactionId subxid = subxids [i ];
21402121
21412122Assert (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+
21442144if (setParent )
21452145SubTransSetParent (xid ,subxid ,overwriteOK );
21462146}
21472147
2148- if (result )
2149- * result = res ;
2150- if (maxsubxid )
2151- * maxsubxid = maxsub ;
2152-
21532148return buf ;
21542149}
21552150