Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbfc79ee

Browse files
simonat2ndQuadrantkelvich
authored andcommitted
Don’t push nextid too far forwards in recovery
Doing so allows various crash possibilities. Fix by avoidinghaving PrescanPreparedTransactions() incrementShmemVariableCache->nextXid when it has no 2PC filesBug found by Jeff Janes, diagnosis and patch by Pavan Deolasee,then patch re-designed for clarity and full accuracy byMichael Paquier.Reported-by: Jeff JanesAuthor: Pavan Deolasee, Michael PaquierDiscussion:https://postgr.es/m/CAMkU=1zMLnH_i1-PVQ-biZzvNx7VcuatriquEnh7HNk6K8Ss3Q@mail.gmail.com
1 parent84d688c commitbfc79ee

File tree

1 file changed

+36
-41
lines changed

1 file changed

+36
-41
lines changed

‎src/backend/access/transam/twophase.c

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ static void XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len);
304304
staticchar*ProcessTwoPhaseBuffer(TransactionIdxid,
305305
XLogRecPtrprepare_start_lsn,
306306
boolfromdisk,booloverwriteOK,boolsetParent,
307-
TransactionId*result,TransactionId*maxsubxid);
307+
boolsetNextXid);
308308
staticvoidMarkAsPreparingGuts(GlobalTransactiongxact,TransactionIdxid,
309309
constchar*gid,TimestampTzprepared_at,Oidowner,
310310
Oiddatabaseid);
@@ -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
TransactionIdorigNextXid=ShmemVariableCache->nextXid;
19761976
TransactionIdresult=origNextXid;
1977-
TransactionIdmaxsubxid=origNextXid;
19781977
TransactionId*xids=NULL;
19791978
intnxids=0;
19801979
intallocsize=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
returnresult;
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
*/
22162212
staticchar*
22172213
ProcessTwoPhaseBuffer(TransactionIdxid,
22182214
XLogRecPtrprepare_start_lsn,
22192215
boolfromdisk,booloverwriteOK,
2220-
boolsetParent,TransactionId*result,
2221-
TransactionId*maxsubxid)
2216+
boolsetParent,boolsetNextXid)
22222217
{
22232218
TransactionIdorigNextXid=ShmemVariableCache->nextXid;
2224-
TransactionIdres=InvalidTransactionId;
2225-
TransactionIdmaxsub=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
returnNULL;
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
TransactionIdsubxid=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
returnbuf;
23532348
}
23542349

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp