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

Commit2ff6555

Browse files
committed
Use the right timeline when beginning to stream from master.
The xlogreader refactoring broke the logic to decide which timeline to startstreaming from. XLogPageRead() uses the timeline history to check whichtimeline the requested WAL position falls into. However, after therefactoring, XLogPageRead() is always first called with the first page inthe segment, to verify the segment header, and only then with the actual WALposition we're interested in. That first read of the segment's header madeXLogPageRead() to always start streaming from the old timeline containingthe segment header, not the timeline containing the actual record, if therewas a timeline switch within the segment.I thought I fixed this yesterday, but that fix was too narrow and only fixedthis for the corner-case that the timeline switch happened in the first pageof the segment. To fix this more robustly, pass explicitly the position ofthe record we're actually interested in to XLogPageRead, and use that todecide which timeline to read from, rather than deduce it from the page andoffset.Per report from Fujii Masao.
1 parent88228e6 commit2ff6555

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

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

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -626,9 +626,10 @@ static int XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli,
626626
intsource,boolnotexistOk);
627627
staticintXLogFileReadAnyTLI(XLogSegNosegno,intemode,intsource);
628628
staticintXLogPageRead(XLogReaderState*xlogreader,XLogRecPtrtargetPagePtr,
629-
intreqLen,char*readBuf,TimeLineID*readTLI);
629+
intreqLen,XLogRecPtrtargetRecPtr,char*readBuf,
630+
TimeLineID*readTLI);
630631
staticboolWaitForWALToBecomeAvailable(XLogRecPtrRecPtr,boolrandAccess,
631-
boolfetching_ckpt);
632+
boolfetching_ckpt,XLogRecPtrtliRecPtr);
632633
staticintemode_for_corrupt_record(intemode,XLogRecPtrRecPtr);
633634
staticvoidXLogFileClose(void);
634635
staticvoidPreallocXlogFiles(XLogRecPtrendptr);
@@ -8832,7 +8833,7 @@ CancelBackup(void)
88328833
*/
88338834
staticint
88348835
XLogPageRead(XLogReaderState*xlogreader,XLogRecPtrtargetPagePtr,intreqLen,
8835-
char*readBuf,TimeLineID*readTLI)
8836+
XLogRecPtrtargetRecPtr,char*readBuf,TimeLineID*readTLI)
88368837
{
88378838
XLogPageReadPrivate*private=
88388839
(XLogPageReadPrivate*)xlogreader->private_data;
@@ -8880,7 +8881,8 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
88808881
{
88818882
if (!WaitForWALToBecomeAvailable(targetPagePtr+reqLen,
88828883
private->randAccess,
8883-
private->fetching_ckpt))
8884+
private->fetching_ckpt,
8885+
targetRecPtr))
88848886
gototriggered;
88858887
}
88868888
/* In archive or crash recovery. */
@@ -8980,19 +8982,27 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
89808982
}
89818983

89828984
/*
8983-
* In standby mode, wait forthe requested record to become available, either
8985+
* In standby mode, wait forWAL at position 'RecPtr' to become available, either
89848986
* via restore_command succeeding to restore the segment, or via walreceiver
89858987
* having streamed the record (or via someone copying the segment directly to
89868988
* pg_xlog, but that is not documented or recommended).
89878989
*
8990+
* If 'fetching_ckpt' is true, we're fetching a checkpoint record, and should
8991+
* prepare to read WAL starting from RedoStartLSN after this.
8992+
*
8993+
* 'RecPtr' might not point to the beginning of the record we're interested
8994+
* in, it might also point to the page or segment header. In that case,
8995+
* 'tliRecPtr' is the position of the WAL record we're interested in. It is
8996+
* used to decide which timeline to stream the requested WAL from.
8997+
*
89888998
* When the requested record becomes available, the function opens the file
89898999
* containing it (if not open already), and returns true. When end of standby
89909000
* mode is triggered by the user, and there is no more WAL available, returns
89919001
* false.
89929002
*/
89939003
staticbool
89949004
WaitForWALToBecomeAvailable(XLogRecPtrRecPtr,boolrandAccess,
8995-
boolfetching_ckpt)
9005+
boolfetching_ckpt,XLogRecPtrtliRecPtr)
89969006
{
89979007
staticpg_time_tlast_fail_time=0;
89989008
pg_time_tnow;
@@ -9076,7 +9086,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess,
90769086
else
90779087
{
90789088
ptr=RecPtr;
9079-
tli=tliOfPointInHistory(ptr,expectedTLEs);
9089+
tli=tliOfPointInHistory(tliRecPtr,expectedTLEs);
90809090

90819091
if (curFileTLI>0&&tli<curFileTLI)
90829092
elog(ERROR,"according to history file, WAL location %X/%X belongs to timeline %u, but previous recovered WAL file came from timeline %u",

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
216216
randAccess= true;/* allow readPageTLI to go backwards too */
217217
}
218218

219+
state->currRecPtr=RecPtr;
220+
219221
targetPagePtr=RecPtr- (RecPtr %XLOG_BLCKSZ);
220222
targetRecOff=RecPtr %XLOG_BLCKSZ;
221223

@@ -503,6 +505,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
503505
XLogRecPtrtargetSegmentPtr=pageptr-targetPageOff;
504506

505507
readLen=state->read_page(state,targetSegmentPtr,XLOG_BLCKSZ,
508+
state->currRecPtr,
506509
state->readBuf,&state->readPageTLI);
507510
if (readLen<0)
508511
gotoerr;
@@ -521,6 +524,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
521524
* so that we can validate it.
522525
*/
523526
readLen=state->read_page(state,pageptr,Max(reqLen,SizeOfXLogShortPHD),
527+
state->currRecPtr,
524528
state->readBuf,&state->readPageTLI);
525529
if (readLen<0)
526530
gotoerr;
@@ -539,6 +543,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen)
539543
if (readLen<XLogPageHeaderSize(hdr))
540544
{
541545
readLen=state->read_page(state,pageptr,XLogPageHeaderSize(hdr),
546+
state->currRecPtr,
542547
state->readBuf,&state->readPageTLI);
543548
if (readLen<0)
544549
gotoerr;

‎src/include/access/xlogreader.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ typedef struct XLogReaderState XLogReaderState;
2727
typedefint (*XLogPageReadCB) (XLogReaderState*xlogreader,
2828
XLogRecPtrtargetPagePtr,
2929
intreqLen,
30+
XLogRecPtrtargetRecPtr,
3031
char*readBuf,
3132
TimeLineID*pageTLI);
3233

@@ -46,11 +47,17 @@ struct XLogReaderState
4647
* -1 on failure. The callback shall sleep, if necessary, to wait for the
4748
* requested bytes to become available. The callback will not be invoked
4849
* again for the same page unless more than the returned number of bytes
49-
* arenecessary.
50+
* areneeded.
5051
*
51-
* *pageTLI should be set to the TLI of the file the page was read from.
52-
* It is currently used only for error reporting purposes, to reconstruct
53-
* the name of the WAL file where an error occurred.
52+
* targetRecPtr is the position of the WAL record we're reading. Usually
53+
* it is equal to targetPagePtr + reqLen, but sometimes xlogreader needs
54+
* to read and verify the page or segment header, before it reads the
55+
* actual WAL record it's interested in. In that case, targetRecPtr can
56+
* be used to determine which timeline to read the page from.
57+
*
58+
* The callback shall set *pageTLI to the TLI of the file the page was
59+
* read from. It is currently used only for error reporting purposes, to
60+
* reconstruct the name of the WAL file where an error occurred.
5461
*/
5562
XLogPageReadCBread_page;
5663

@@ -90,6 +97,9 @@ struct XLogReaderState
9097
XLogRecPtrlatestPagePtr;
9198
TimeLineIDlatestPageTLI;
9299

100+
/* beginning of the WAL record being read. */
101+
XLogRecPtrcurrRecPtr;
102+
93103
/* Buffer for current ReadRecord result (expandable) */
94104
char*readRecordBuf;
95105
uint32readRecordBufSize;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp