@@ -304,7 +304,7 @@ static void XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len);
304304static char * ProcessTwoPhaseBuffer (TransactionId xid ,
305305 XLogRecPtr prepare_start_lsn ,
306306 bool fromdisk , bool overwriteOK , bool setParent ,
307- TransactionId * result , TransactionId * maxsubxid );
307+ bool setNextXid );
308308static void MarkAsPreparingGuts (GlobalTransaction gxact , TransactionId xid ,
309309 const char * gid , TimestampTz prepared_at , Oid owner ,
310310 Oid databaseid );
@@ -1931,7 +1931,7 @@ restoreTwoPhaseData(void)
19311931
19321932 buf = ProcessTwoPhaseBuffer (xid , InvalidXLogRecPtr ,
19331933 true, false, false,
1934- NULL , NULL );
1934+ false );
19351935 if (buf == NULL )
19361936 continue ;
19371937
@@ -1974,7 +1974,6 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
19741974{
19751975 TransactionId origNextXid = ShmemVariableCache -> nextXid ;
19761976 TransactionId result = origNextXid ;
1977- TransactionId maxsubxid = origNextXid ;
19781977 TransactionId * xids = NULL ;
19791978 int nxids = 0 ;
19801979 int allocsize = 0 ;
@@ -1994,11 +1993,18 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
19941993 buf = ProcessTwoPhaseBuffer (xid ,
19951994 gxact -> prepare_start_lsn ,
19961995 gxact -> ondisk , false, false,
1997- & result , & maxsubxid );
1996+ true );
19981997
19991998 if (buf == NULL )
20001999 continue ;
20012000
2001+ /*
2002+ * OK, we think this file is valid. Incorporate xid into the
2003+ * running-minimum result.
2004+ */
2005+ if (TransactionIdPrecedes (xid , result ))
2006+ result = xid ;
2007+
20022008 if (xids_p )
20032009 {
20042010 if (nxids == allocsize )
@@ -2027,15 +2033,6 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
20272033 * nxids_p = nxids ;
20282034 }
20292035
2030- /* update nextXid if needed */
2031- if (TransactionIdFollowsOrEquals (maxsubxid , ShmemVariableCache -> nextXid ))
2032- {
2033- LWLockAcquire (XidGenLock , LW_EXCLUSIVE );
2034- ShmemVariableCache -> nextXid = maxsubxid ;
2035- TransactionIdAdvance (ShmemVariableCache -> nextXid );
2036- LWLockRelease (XidGenLock );
2037- }
2038-
20392036 return result ;
20402037}
20412038
@@ -2072,7 +2069,7 @@ StandbyRecoverPreparedTransactions(bool overwriteOK)
20722069 buf = ProcessTwoPhaseBuffer (xid ,
20732070 gxact -> prepare_start_lsn ,
20742071 gxact -> ondisk , overwriteOK , true,
2075- NULL , NULL );
2072+ false );
20762073 if (buf != NULL )
20772074 pfree (buf );
20782075 }
@@ -2118,7 +2115,7 @@ RecoverPreparedTransactions(void)
21182115 buf = ProcessTwoPhaseBuffer (xid ,
21192116 gxact -> prepare_start_lsn ,
21202117 gxact -> ondisk , false, false,
2121- NULL , NULL );
2118+ false );
21222119 if (buf == NULL )
21232120 continue ;
21242121
@@ -2209,20 +2206,16 @@ RecoverPreparedTransactions(void)
22092206 * If setParent is true, then use the overwriteOK parameter to set up
22102207 * subtransaction parent linkages.
22112208 *
2212- * If result and maxsubxid are not NULL, fill them up with smallest
2213- * running transaction id (lesser than ShmemVariableCache->nextXid)
2214- * and largest subtransaction id for this transaction respectively.
2209+ * If setNextXid is true, set ShmemVariableCache->nextXid to the newest
2210+ * value scanned.
22152211 */
22162212static char *
22172213ProcessTwoPhaseBuffer (TransactionId xid ,
22182214 XLogRecPtr prepare_start_lsn ,
22192215 bool fromdisk , bool overwriteOK ,
2220- bool setParent , TransactionId * result ,
2221- TransactionId * maxsubxid )
2216+ bool setParent , bool setNextXid )
22222217{
22232218 TransactionId origNextXid = ShmemVariableCache -> nextXid ;
2224- TransactionId res = InvalidTransactionId ;
2225- TransactionId maxsub = InvalidTransactionId ;
22262219 TransactionId * subxids ;
22272220 char * buf ;
22282221 TwoPhaseFileHeader * hdr ;
@@ -2233,11 +2226,6 @@ ProcessTwoPhaseBuffer(TransactionId xid,
22332226 if (!fromdisk )
22342227 Assert (prepare_start_lsn != InvalidXLogRecPtr );
22352228
2236- if (result )
2237- res = * result ;
2238- if (maxsubxid )
2239- maxsub = * maxsubxid ;
2240-
22412229 /* Already processed? */
22422230 if (TransactionIdDidCommit (xid ) || TransactionIdDidAbort (xid ))
22432231 {
@@ -2319,13 +2307,6 @@ ProcessTwoPhaseBuffer(TransactionId xid,
23192307 return NULL ;
23202308 }
23212309
2322- /*
2323- * OK, we think this buffer is valid. Incorporate xid into the
2324- * running-minimum result.
2325- */
2326- if (TransactionIdPrecedes (xid , res ))
2327- res = xid ;
2328-
23292310 /*
23302311 * Examine subtransaction XIDs ... they should all follow main
23312312 * XID, and they may force us to advance nextXid.
@@ -2338,17 +2319,31 @@ ProcessTwoPhaseBuffer(TransactionId xid,
23382319 TransactionId subxid = subxids [i ];
23392320
23402321 Assert (TransactionIdFollows (subxid , xid ));
2341- if (TransactionIdFollowsOrEquals (subxid , maxsub ))
2342- maxsub = subxid ;
2322+
2323+ /* update nextXid if needed */
2324+ if (setNextXid &&
2325+ TransactionIdFollowsOrEquals (subxid ,
2326+ ShmemVariableCache -> nextXid ))
2327+ {
2328+ /*
2329+ * We don't expect anyone else to modify nextXid, hence we don't
2330+ * need to hold a lock while examining it. We still acquire the
2331+ * lock to modify it, though, so we recheck.
2332+ */
2333+ LWLockAcquire (XidGenLock , LW_EXCLUSIVE );
2334+ if (TransactionIdFollowsOrEquals (subxid ,
2335+ ShmemVariableCache -> nextXid ))
2336+ {
2337+ ShmemVariableCache -> nextXid = subxid ;
2338+ TransactionIdAdvance (ShmemVariableCache -> nextXid );
2339+ }
2340+ LWLockRelease (XidGenLock );
2341+ }
2342+
23432343 if (setParent )
23442344 SubTransSetParent (xid , subxid , overwriteOK );
23452345 }
23462346
2347- if (result )
2348- * result = res ;
2349- if (maxsubxid )
2350- * maxsubxid = maxsub ;
2351-
23522347 return buf ;
23532348}
23542349
0 commit comments