aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/transam/xlog.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index ef72bde0123..757760eadae 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -4419,12 +4419,18 @@ ReadRecord(XLogReaderState *xlogreader, int emode,
if (record == NULL)
{
/*
- * When not in standby mode we find that WAL ends in an incomplete
- * record, keep track of that record. After recovery is done,
- * we'll write a record to indicate downstream WAL readers that
- * that portion is to be ignored.
+ * When we find that WAL ends in an incomplete record, keep track
+ * of that record. After recovery is done, we'll write a record to
+ * indicate to downstream WAL readers that that portion is to be
+ * ignored.
+ *
+ * However, when ArchiveRecoveryRequested = true, we're going to
+ * switch to a new timeline at the end of recovery. We will only
+ * copy WAL over to the new timeline up to the end of the last
+ * complete record, so if we did this, we would later create an
+ * overwrite contrecord in the wrong place, breaking everything.
*/
- if (!StandbyMode &&
+ if (!ArchiveRecoveryRequested &&
!XLogRecPtrIsInvalid(xlogreader->abortedRecPtr))
{
abortedRecPtr = xlogreader->abortedRecPtr;
@@ -7866,6 +7872,14 @@ StartupXLOG(void)
*/
if (!XLogRecPtrIsInvalid(missingContrecPtr))
{
+ /*
+ * We should only have a missingContrecPtr if we're not switching to
+ * a new timeline. When a timeline switch occurs, WAL is copied from
+ * the old timeline to the new only up to the end of the last complete
+ * record, so there can't be an incomplete WAL record that we need to
+ * disregard.
+ */
+ Assert(ThisTimeLineID == PrevTimeLineID);
Assert(!XLogRecPtrIsInvalid(abortedRecPtr));
EndOfLog = missingContrecPtr;
}