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

Commitaa203e7

Browse files
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 parent51175f3 commitaa203e7

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
@@ -222,7 +222,7 @@ static void XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len);
222222
staticchar*ProcessTwoPhaseBuffer(TransactionIdxid,
223223
XLogRecPtrprepare_start_lsn,
224224
boolfromdisk,booloverwriteOK,boolsetParent,
225-
TransactionId*result,TransactionId*maxsubxid);
225+
boolsetNextXid);
226226
staticvoidMarkAsPreparingGuts(GlobalTransactiongxact,TransactionIdxid,
227227
constchar*gid,TimestampTzprepared_at,Oidowner,
228228
Oiddatabaseid);
@@ -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
TransactionIdorigNextXid=ShmemVariableCache->nextXid;
17881788
TransactionIdresult=origNextXid;
1789-
TransactionIdmaxsubxid=origNextXid;
17901789
TransactionId*xids=NULL;
17911790
intnxids=0;
17921791
intallocsize=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
returnresult;
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
*/
20192015
staticchar*
20202016
ProcessTwoPhaseBuffer(TransactionIdxid,
20212017
XLogRecPtrprepare_start_lsn,
20222018
boolfromdisk,booloverwriteOK,
2023-
boolsetParent,TransactionId*result,
2024-
TransactionId*maxsubxid)
2019+
boolsetParent,boolsetNextXid)
20252020
{
20262021
TransactionIdorigNextXid=ShmemVariableCache->nextXid;
2027-
TransactionIdres=InvalidTransactionId;
2028-
TransactionIdmaxsub=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
returnNULL;
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
TransactionIdsubxid=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
returnbuf;
21542149
}
21552150

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp