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

Commite7ea2fa

Browse files
committed
Fix corner-case failure to detect improper timeline switch.
rescanLatestTimeLine() contains a guard against switching toa timeline that forked off from the current one prior to thecurrent recovery point, but that guard does not work if thetimeline switch occurs before the first WAL recod (which mustbe the checkpoint record) is read. Without this patch, animproper timeline switch is therefore possible in such cases.This happens because rescanLatestTimeLine() relies on the globalvariable EndRecPtr to understand the current position of WALreplay. However, EndRecPtr at this point in the code containsthe endpoint of the last-replayed record, not the startpoint orendpoint of the record being replayed now. Thus, before anyrecords have been replayed, it's zero, which causes the sanitycheck to always pass.To fix, pass down the correct timeline explicitly. TheEndRecPtr value we want is the one from the xlogreader, whichwill be the starting position of the record we're about totry to read, rather than the global variable, which is theending position of the last record we successfully read.They're usually the same, but not in the corner case describedhere.No back-patch, because in v14 and earlier branhes, we were usingthe wrong TLI here as well as the wrong LSN. In master, that wasfixed by commit4a92a1c, butthat and it's prerequisite patches are too invasive toback-patch for such a minor issue.Patch by me, reviewed by Amul Sul.Discussion:http://postgr.es/m/CA+Tgmoao96EuNeSPd+hspRKcsCddu=b1h-QNRuKfY8VmfNQdfg@mail.gmail.com
1 parentf79962d commite7ea2fa

File tree

1 file changed

+16
-9
lines changed
  • src/backend/access/transam

1 file changed

+16
-9
lines changed

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

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,8 @@ static intXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr,
924924
intreqLen,XLogRecPtrtargetRecPtr,char*readBuf);
925925
staticboolWaitForWALToBecomeAvailable(XLogRecPtrRecPtr,boolrandAccess,
926926
boolfetching_ckpt,XLogRecPtrtliRecPtr,
927-
TimeLineIDreplayTLI);
927+
TimeLineIDreplayTLI,
928+
XLogRecPtrreplayLSN);
928929
staticvoidXLogShutdownWalRcv(void);
929930
staticintemode_for_corrupt_record(intemode,XLogRecPtrRecPtr);
930931
staticvoidXLogFileClose(void);
@@ -946,7 +947,8 @@ static bool PerformRecoveryXLogAction(void);
946947
staticXLogRecord*ReadCheckpointRecord(XLogReaderState*xlogreader,
947948
XLogRecPtrRecPtr,intwhichChkpt,boolreport,
948949
TimeLineIDreplayTLI);
949-
staticboolrescanLatestTimeLine(TimeLineIDreplayTLI);
950+
staticboolrescanLatestTimeLine(TimeLineIDreplayTLI,
951+
XLogRecPtrreplayLSN);
950952
staticvoidInitControlFile(uint64sysidentifier);
951953
staticvoidWriteControlFile(void);
952954
staticvoidReadControlFile(void);
@@ -4620,7 +4622,7 @@ ReadRecord(XLogReaderState *xlogreader, int emode,
46204622
* one and returns 'true'.
46214623
*/
46224624
staticbool
4623-
rescanLatestTimeLine(TimeLineIDreplayTLI)
4625+
rescanLatestTimeLine(TimeLineIDreplayTLI,XLogRecPtrreplayLSN)
46244626
{
46254627
List*newExpectedTLEs;
46264628
boolfound;
@@ -4671,13 +4673,13 @@ rescanLatestTimeLine(TimeLineID replayTLI)
46714673
* next timeline was forked off from it *after* the current recovery
46724674
* location.
46734675
*/
4674-
if (currentTle->end<EndRecPtr)
4676+
if (currentTle->end<replayLSN)
46754677
{
46764678
ereport(LOG,
46774679
(errmsg("new timeline %u forked off current database system timeline %u before current recovery point %X/%X",
46784680
newtarget,
46794681
replayTLI,
4680-
LSN_FORMAT_ARGS(EndRecPtr))));
4682+
LSN_FORMAT_ARGS(replayLSN))));
46814683
return false;
46824684
}
46834685

@@ -12473,7 +12475,8 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
1247312475
private->randAccess,
1247412476
private->fetching_ckpt,
1247512477
targetRecPtr,
12476-
private->replayTLI))
12478+
private->replayTLI,
12479+
xlogreader->EndRecPtr))
1247712480
{
1247812481
if (readFile >=0)
1247912482
close(readFile);
@@ -12626,6 +12629,10 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
1262612629
* 'tliRecPtr' is the position of the WAL record we're interested in. It is
1262712630
* used to decide which timeline to stream the requested WAL from.
1262812631
*
12632+
* 'replayLSN' is the current replay LSN, so that if we scan for new
12633+
* timelines, we can reject a switch to a timeline that branched off before
12634+
* this point.
12635+
*
1262912636
* If the record is not immediately available, the function returns false
1263012637
* if we're not in standby mode. In standby mode, waits for it to become
1263112638
* available.
@@ -12638,7 +12645,7 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
1263812645
staticbool
1263912646
WaitForWALToBecomeAvailable(XLogRecPtrRecPtr,boolrandAccess,
1264012647
boolfetching_ckpt,XLogRecPtrtliRecPtr,
12641-
TimeLineIDreplayTLI)
12648+
TimeLineIDreplayTLI,XLogRecPtrreplayLSN)
1264212649
{
1264312650
staticTimestampTzlast_fail_time=0;
1264412651
TimestampTznow;
@@ -12761,7 +12768,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
1276112768
*/
1276212769
if (recoveryTargetTimeLineGoal==RECOVERY_TARGET_TIMELINE_LATEST)
1276312770
{
12764-
if (rescanLatestTimeLine(replayTLI))
12771+
if (rescanLatestTimeLine(replayTLI,replayLSN))
1276512772
{
1276612773
currentSource=XLOG_FROM_ARCHIVE;
1276712774
break;
@@ -12888,7 +12895,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
1288812895
*/
1288912896
if (recoveryTargetTimeLineGoal==
1289012897
RECOVERY_TARGET_TIMELINE_LATEST)
12891-
rescanLatestTimeLine(replayTLI);
12898+
rescanLatestTimeLine(replayTLI,replayLSN);
1289212899

1289312900
startWalReceiver= true;
1289412901
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp