From 8932a390bd3d1acfe5722bc62f42fc7e381ca617 Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi Date: Thu, 7 Sep 2017 12:14:55 +0900 Subject: [PATCH 1/2] Allow switch WAL source midst of record. The corrent recovery machinary assumes the whole of a record is avaiable from single source. This prevents a standby from restarting under a certain condition. This patch allows source switching during reading a series of continuation records. --- src/backend/access/transam/xlog.c | 7 ++++++- src/backend/access/transam/xlogreader.c | 12 +++++------- src/include/access/xlogreader.h | 5 +++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index df4843f..eef3a97 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -11566,6 +11566,11 @@ retry: Assert(reqLen <= readLen); *readTLI = curFileTLI; + + if (!XLogReaderValidatePageHeader(xlogreader, targetPagePtr, + (XLogPageHeader) readBuf)) + goto next_record_is_invalid; + return readLen; next_record_is_invalid: @@ -11700,7 +11705,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, } else { - ptr = tliRecPtr; + ptr = RecPtr; tli = tliOfPointInHistory(tliRecPtr, expectedTLEs); if (curFileTLI > 0 && tli < curFileTLI) diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index 0781a7b..aa05e3f 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -27,8 +27,6 @@ static bool allocate_recordbuf(XLogReaderState *state, uint32 reclength); -static bool ValidXLogPageHeader(XLogReaderState *state, XLogRecPtr recptr, - XLogPageHeader hdr); static bool ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr, XLogRecPtr PrevRecPtr, XLogRecord *record, bool randAccess); static bool ValidXLogRecord(XLogReaderState *state, XLogRecord *record, @@ -545,7 +543,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen) hdr = (XLogPageHeader) state->readBuf; - if (!ValidXLogPageHeader(state, targetSegmentPtr, hdr)) + if (!XLogReaderValidatePageHeader(state, targetSegmentPtr, hdr)) goto err; } @@ -582,7 +580,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen) /* * Now that we know we have the full header, validate it. */ - if (!ValidXLogPageHeader(state, pageptr, hdr)) + if (!XLogReaderValidatePageHeader(state, pageptr, hdr)) goto err; /* update read state information */ @@ -709,9 +707,9 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr) /* * Validate a page header */ -static bool -ValidXLogPageHeader(XLogReaderState *state, XLogRecPtr recptr, - XLogPageHeader hdr) +bool +XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr, + XLogPageHeader hdr) { XLogRecPtr recaddr; XLogSegNo segno; diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h index 7671598..11b63e7 100644 --- a/src/include/access/xlogreader.h +++ b/src/include/access/xlogreader.h @@ -28,6 +28,7 @@ #include "access/xlogrecord.h" typedef struct XLogReaderState XLogReaderState; +typedef struct XLogPageHeaderData *XLogPageHeader; /* Function type definition for the read_page callback */ typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader, @@ -199,6 +200,10 @@ extern void XLogReaderFree(XLogReaderState *state); extern struct XLogRecord *XLogReadRecord(XLogReaderState *state, XLogRecPtr recptr, char **errormsg); +/* Validate a page */ +extern bool XLogReaderValidatePageHeader(XLogReaderState *state, + XLogRecPtr recptr, XLogPageHeader hdr); + /* Invalidate read state */ extern void XLogReaderInvalReadState(XLogReaderState *state); -- 2.9.2