diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c new file mode 100644 index fd93bcf..5dd777f *** a/src/backend/access/transam/xlog.c --- b/src/backend/access/transam/xlog.c *************** static void SetCurrentChunkStartTime(Tim *** 896,902 **** static void CheckRequiredParameterValues(void); static void XLogReportParameters(void); static void checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, ! TimeLineID prevTLI); static void LocalSetXLogInsertAllowed(void); static void CreateEndOfRecoveryRecord(void); static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags); --- 896,902 ---- static void CheckRequiredParameterValues(void); static void XLogReportParameters(void); static void checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, ! TimeLineID prevTLI, bool pgrewind_replay); static void LocalSetXLogInsertAllowed(void); static void CreateEndOfRecoveryRecord(void); static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags); *************** static void xlog_outdesc(StringInfo buf, *** 946,952 **** static void pg_start_backup_callback(int code, Datum arg); static void pg_stop_backup_callback(int code, Datum arg); static bool read_backup_label(XLogRecPtr *checkPointLoc, ! bool *backupEndRequired, bool *backupFromStandby); static bool read_tablespace_map(List **tablespaces); static void rm_redo_error_callback(void *arg); --- 946,952 ---- static void pg_start_backup_callback(int code, Datum arg); static void pg_stop_backup_callback(int code, Datum arg); static bool read_backup_label(XLogRecPtr *checkPointLoc, ! bool *backupEndRequired, bool *backupFromStandby, bool *pgrewind_replay); static bool read_tablespace_map(List **tablespaces); static void rm_redo_error_callback(void *arg); *************** StartupXLOG(void) *** 6319,6324 **** --- 6319,6325 ---- TransactionId oldestActiveXID; bool backupEndRequired = false; bool backupFromStandby = false; + bool pgrewind_replay = false; DBState dbstate_at_startup; XLogReaderState *xlogreader; XLogPageReadPrivate private; *************** StartupXLOG(void) *** 6506,6512 **** master_image_masked = (char *) palloc(BLCKSZ); if (read_backup_label(&checkPointLoc, &backupEndRequired, ! &backupFromStandby)) { List *tablespaces = NIL; --- 6507,6513 ---- master_image_masked = (char *) palloc(BLCKSZ); if (read_backup_label(&checkPointLoc, &backupEndRequired, ! &backupFromStandby, &pgrewind_replay)) { List *tablespaces = NIL; *************** StartupXLOG(void) *** 7297,7303 **** if (newTLI != ThisTimeLineID) { /* Check that it's OK to switch to this TLI */ ! checkTimeLineSwitch(EndRecPtr, newTLI, prevTLI); /* Following WAL records should be run with new TLI */ ThisTimeLineID = newTLI; --- 7298,7304 ---- if (newTLI != ThisTimeLineID) { /* Check that it's OK to switch to this TLI */ ! checkTimeLineSwitch(EndRecPtr, newTLI, prevTLI, pgrewind_replay); /* Following WAL records should be run with new TLI */ ThisTimeLineID = newTLI; *************** UpdateFullPageWrites(void) *** 9841,9847 **** * replay. (Currently, timeline can only change at a shutdown checkpoint). */ static void ! checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI) { /* Check that the record agrees on what the current (old) timeline is */ if (prevTLI != ThisTimeLineID) --- 9842,9848 ---- * replay. (Currently, timeline can only change at a shutdown checkpoint). */ static void ! checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, TimeLineID prevTLI, bool pgrewind_replay) { /* Check that the record agrees on what the current (old) timeline is */ if (prevTLI != ThisTimeLineID) *************** checkTimeLineSwitch(XLogRecPtr lsn, Time *** 9877,9882 **** --- 9878,9894 ---- (uint32) minRecoveryPoint, minRecoveryPointTLI))); + /* + * If we have not yet found the end of a backup that had been performed + * then switching to a new timeline is similairly trouble, as there's + * zero chance we'll find the end-of-backup WAL record on the new timeline. + */ + if (InArchiveRecovery && !reachedConsistency && !pgrewind_replay) + ereport(PANIC, + (errmsg("unexpected timeline ID %u in checkpoint record, before finding end-of-backup WAL record on timeline %u", + newTLI, + ThisTimeLineID))); + /* Looks good */ } *************** GetOldestRestartPoint(XLogRecPtr *oldrec *** 11541,11547 **** */ static bool read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, ! bool *backupFromStandby) { char startxlogfilename[MAXFNAMELEN]; TimeLineID tli_from_walseg, --- 11553,11559 ---- */ static bool read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, ! bool *backupFromStandby, bool *pgrewind_replay) { char startxlogfilename[MAXFNAMELEN]; TimeLineID tli_from_walseg, *************** read_backup_label(XLogRecPtr *checkPoint *** 11599,11604 **** --- 11611,11618 ---- { if (strcmp(backuptype, "streamed") == 0) *backupEndRequired = true; + if (strcmp(backuptype, "pg_rewind") == 0) + *pgrewind_replay = true; } if (fscanf(lfp, "BACKUP FROM: %19s\n", backupfrom) == 1)