diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 537845cada7..fbf2d34eef9 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -5433,6 +5433,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(newTLI == endOfRecoveryInfo->lastRecTLI); Assert(!XLogRecPtrIsInvalid(abortedRecPtr)); EndOfLog = missingContrecPtr; } diff --git a/src/backend/access/transam/xlogrecovery.c b/src/backend/access/transam/xlogrecovery.c index a59a0e826bb..4ad145dd167 100644 --- a/src/backend/access/transam/xlogrecovery.c +++ b/src/backend/access/transam/xlogrecovery.c @@ -3024,12 +3024,18 @@ ReadRecord(XLogPrefetcher *xlogprefetcher, 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 to 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;