cascading_standby_stuck.patch
application/octet-stream
Filename: cascading_standby_stuck.patch
Type: application/octet-stream
Part: 0
Patch
Format: context
| File | + | − |
|---|---|---|
| src/backend/access/transam/xlog.c | 21 | 36 |
diff -Nacr a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
*** a/src/backend/access/transam/xlog.c 2016-08-09 05:33:27.000000000 +0900
--- b/src/backend/access/transam/xlog.c 2016-08-26 10:27:55.000000000 +0900
***************
*** 589,596 ****
/* State information for XLOG reading */
static XLogRecPtr ReadRecPtr; /* start of last record read */
static XLogRecPtr EndRecPtr; /* end+1 of last record read */
! static TimeLineID lastPageTLI = 0;
! static TimeLineID lastSegmentTLI = 0;
static XLogRecPtr minRecoveryPoint; /* local copy of
* ControlFile->minRecoveryPoint */
--- 589,596 ----
/* State information for XLOG reading */
static XLogRecPtr ReadRecPtr; /* start of last record read */
static XLogRecPtr EndRecPtr; /* end+1 of last record read */
! static XLogRecPtr latestPagePtr; /* start of last page read */
! static TimeLineID latestPageTLI = 0;
static XLogRecPtr minRecoveryPoint; /* local copy of
* ControlFile->minRecoveryPoint */
***************
*** 678,684 ****
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force);
static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt);
static void CheckRecoveryConsistency(void);
! static bool ValidXLOGHeader(XLogPageHeader hdr, int emode, bool segmentonly);
static XLogRecord *ReadCheckpointRecord(XLogRecPtr RecPtr, int whichChkpt);
static List *readTimeLineHistory(TimeLineID targetTLI);
static bool existsTimeLineHistory(TimeLineID probeTLI);
--- 678,684 ----
static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force);
static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt);
static void CheckRecoveryConsistency(void);
! static bool ValidXLOGHeader(XLogPageHeader hdr, int emode);
static XLogRecord *ReadCheckpointRecord(XLogRecPtr RecPtr, int whichChkpt);
static List *readTimeLineHistory(TimeLineID targetTLI);
static bool existsTimeLineHistory(TimeLineID probeTLI);
***************
*** 3992,4005 ****
(errmsg("invalid record offset at %X/%X",
RecPtr->xlogid, RecPtr->xrecoff)));
- /*
- * Since we are going to a random position in WAL, forget any prior
- * state about what timeline we were in, and allow it to be any
- * timeline in expectedTLIs. We also set a flag to allow curFileTLI
- * to go backwards (but we can't reset that variable right here, since
- * we might not change files at all).
- */
- lastPageTLI = lastSegmentTLI = 0; /* see comment in ValidXLOGHeader */
randAccess = true; /* allow curFileTLI to go backwards too */
}
--- 3992,3997 ----
***************
*** 4317,4323 ****
* ReadRecord. It's not intended for use from anywhere else.
*/
static bool
! ValidXLOGHeader(XLogPageHeader hdr, int emode, bool segmentonly)
{
XLogRecPtr recaddr;
--- 4309,4315 ----
* ReadRecord. It's not intended for use from anywhere else.
*/
static bool
! ValidXLOGHeader(XLogPageHeader hdr, int emode)
{
XLogRecPtr recaddr;
***************
*** 4411,4441 ****
* immediate parent's TLI, we should never see TLI go backwards across
* successive pages of a consistent WAL sequence.
*
! * Of course this check should only be applied when advancing sequentially
! * across pages; therefore ReadRecord resets lastPageTLI and
! * lastSegmentTLI to zero when going to a random page.
! *
! * Sometimes we re-open a segment that's already been partially replayed.
! * In that case we cannot perform the normal TLI check: if there is a
! * timeline switch within the segment, the first page has a smaller TLI
! * than later pages following the timeline switch, and we might've read
! * them already. As a weaker test, we still check that it's not smaller
! * than the TLI we last saw at the beginning of a segment. Pass
! * segmentonly = true when re-validating the first page like that, and the
! * page you're actually interested in comes later.
*/
! if (hdr->xlp_tli < (segmentonly ? lastSegmentTLI : lastPageTLI))
{
! ereport(emode_for_corrupt_record(emode, recaddr),
! (errmsg("out-of-sequence timeline ID %u (after %u) in log file %u, segment %u, offset %u",
! hdr->xlp_tli,
! segmentonly ? lastSegmentTLI : lastPageTLI,
! readId, readSeg, readOff)));
! return false;
}
! lastPageTLI = hdr->xlp_tli;
! if (readOff == 0)
! lastSegmentTLI = hdr->xlp_tli;
return true;
}
--- 4403,4426 ----
* immediate parent's TLI, we should never see TLI go backwards across
* successive pages of a consistent WAL sequence.
*
! * Sometimes we re-read a segment that's already been (partially) read. So
! * we only verify TLIs for pages that are later than the last remembered
! * LSN.
*/
! if (XLByteLT(latestPagePtr, recaddr))
{
! if (hdr->xlp_tli < latestPageTLI)
! {
! ereport(emode_for_corrupt_record(emode, recaddr),
! (errmsg("out-of-sequence timeline ID %u (after %u) in log file %u, segment %u, offset %u",
! hdr->xlp_tli,
! latestPageTLI,
! readId, readSeg, readOff)));
! return false;
! }
}
! latestPagePtr = recaddr;
! latestPageTLI = hdr->xlp_tli;
return true;
}
***************
*** 10803,10809 ****
readId, readSeg, readOff)));
goto next_record_is_invalid;
}
! if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode, true))
goto next_record_is_invalid;
}
--- 10788,10794 ----
readId, readSeg, readOff)));
goto next_record_is_invalid;
}
! if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode))
goto next_record_is_invalid;
}
***************
*** 10825,10831 ****
readId, readSeg, readOff)));
goto next_record_is_invalid;
}
! if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode, false))
goto next_record_is_invalid;
Assert(targetId == readId);
--- 10810,10816 ----
readId, readSeg, readOff)));
goto next_record_is_invalid;
}
! if (!ValidXLOGHeader((XLogPageHeader) readBuf, emode))
goto next_record_is_invalid;
Assert(targetId == readId);