@@ -304,7 +304,7 @@ static void XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len);
304
304
static char * ProcessTwoPhaseBuffer (TransactionId xid ,
305
305
XLogRecPtr prepare_start_lsn ,
306
306
bool fromdisk , bool overwriteOK , bool setParent ,
307
- TransactionId * result , TransactionId * maxsubxid );
307
+ bool setNextXid );
308
308
static void MarkAsPreparingGuts (GlobalTransaction gxact , TransactionId xid ,
309
309
const char * gid , TimestampTz prepared_at , Oid owner ,
310
310
Oid databaseid );
@@ -1931,7 +1931,7 @@ restoreTwoPhaseData(void)
1931
1931
1932
1932
buf = ProcessTwoPhaseBuffer (xid , InvalidXLogRecPtr ,
1933
1933
true, false, false,
1934
- NULL , NULL );
1934
+ false );
1935
1935
if (buf == NULL )
1936
1936
continue ;
1937
1937
@@ -1974,7 +1974,6 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
1974
1974
{
1975
1975
TransactionId origNextXid = ShmemVariableCache -> nextXid ;
1976
1976
TransactionId result = origNextXid ;
1977
- TransactionId maxsubxid = origNextXid ;
1978
1977
TransactionId * xids = NULL ;
1979
1978
int nxids = 0 ;
1980
1979
int allocsize = 0 ;
@@ -1994,11 +1993,18 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
1994
1993
buf = ProcessTwoPhaseBuffer (xid ,
1995
1994
gxact -> prepare_start_lsn ,
1996
1995
gxact -> ondisk , false, false,
1997
- & result , & maxsubxid );
1996
+ true );
1998
1997
1999
1998
if (buf == NULL )
2000
1999
continue ;
2001
2000
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
+
2002
2008
if (xids_p )
2003
2009
{
2004
2010
if (nxids == allocsize )
@@ -2027,15 +2033,6 @@ PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p)
2027
2033
* nxids_p = nxids ;
2028
2034
}
2029
2035
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
-
2039
2036
return result ;
2040
2037
}
2041
2038
@@ -2072,7 +2069,7 @@ StandbyRecoverPreparedTransactions(bool overwriteOK)
2072
2069
buf = ProcessTwoPhaseBuffer (xid ,
2073
2070
gxact -> prepare_start_lsn ,
2074
2071
gxact -> ondisk , overwriteOK , true,
2075
- NULL , NULL );
2072
+ false );
2076
2073
if (buf != NULL )
2077
2074
pfree (buf );
2078
2075
}
@@ -2118,7 +2115,7 @@ RecoverPreparedTransactions(void)
2118
2115
buf = ProcessTwoPhaseBuffer (xid ,
2119
2116
gxact -> prepare_start_lsn ,
2120
2117
gxact -> ondisk , false, false,
2121
- NULL , NULL );
2118
+ false );
2122
2119
if (buf == NULL )
2123
2120
continue ;
2124
2121
@@ -2209,20 +2206,16 @@ RecoverPreparedTransactions(void)
2209
2206
* If setParent is true, then use the overwriteOK parameter to set up
2210
2207
* subtransaction parent linkages.
2211
2208
*
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.
2215
2211
*/
2216
2212
static char *
2217
2213
ProcessTwoPhaseBuffer (TransactionId xid ,
2218
2214
XLogRecPtr prepare_start_lsn ,
2219
2215
bool fromdisk , bool overwriteOK ,
2220
- bool setParent , TransactionId * result ,
2221
- TransactionId * maxsubxid )
2216
+ bool setParent , bool setNextXid )
2222
2217
{
2223
2218
TransactionId origNextXid = ShmemVariableCache -> nextXid ;
2224
- TransactionId res = InvalidTransactionId ;
2225
- TransactionId maxsub = InvalidTransactionId ;
2226
2219
TransactionId * subxids ;
2227
2220
char * buf ;
2228
2221
TwoPhaseFileHeader * hdr ;
@@ -2233,11 +2226,6 @@ ProcessTwoPhaseBuffer(TransactionId xid,
2233
2226
if (!fromdisk )
2234
2227
Assert (prepare_start_lsn != InvalidXLogRecPtr );
2235
2228
2236
- if (result )
2237
- res = * result ;
2238
- if (maxsubxid )
2239
- maxsub = * maxsubxid ;
2240
-
2241
2229
/* Already processed? */
2242
2230
if (TransactionIdDidCommit (xid ) || TransactionIdDidAbort (xid ))
2243
2231
{
@@ -2319,13 +2307,6 @@ ProcessTwoPhaseBuffer(TransactionId xid,
2319
2307
return NULL ;
2320
2308
}
2321
2309
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
-
2329
2310
/*
2330
2311
* Examine subtransaction XIDs ... they should all follow main
2331
2312
* XID, and they may force us to advance nextXid.
@@ -2338,17 +2319,31 @@ ProcessTwoPhaseBuffer(TransactionId xid,
2338
2319
TransactionId subxid = subxids [i ];
2339
2320
2340
2321
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
+
2343
2343
if (setParent )
2344
2344
SubTransSetParent (xid , subxid , overwriteOK );
2345
2345
}
2346
2346
2347
- if (result )
2348
- * result = res ;
2349
- if (maxsubxid )
2350
- * maxsubxid = maxsub ;
2351
-
2352
2347
return buf ;
2353
2348
}
2354
2349
0 commit comments