@@ -4828,6 +4828,22 @@ StartupXLOG(void)
48284828ereport (LOG ,
48294829(errmsg ("starting archive recovery" )));
48304830}
4831+ else if (ControlFile -> minRecoveryPointTLI > 0 )
4832+ {
4833+ /*
4834+ * If the minRecoveryPointTLI is set when not in Archive Recovery
4835+ * it means that we have crashed after ending recovery and
4836+ * yet before we wrote a new checkpoint on the new timeline.
4837+ * That means we are doing a crash recovery that needs to cross
4838+ * timelines to get to our newly assigned timeline again.
4839+ * The timeline we are headed for is exact and not 'latest'.
4840+ * As soon as we hit a checkpoint, the minRecoveryPointTLI is
4841+ * reset, so we will not enter crash recovery again.
4842+ */
4843+ Assert (ControlFile -> minRecoveryPointTLI != 1 );
4844+ recoveryTargetTLI = ControlFile -> minRecoveryPointTLI ;
4845+ recoveryTargetIsLatest = false;
4846+ }
48314847
48324848/*
48334849 * Take ownership of the wakeup latch if we're going to sleep during
@@ -5075,6 +5091,12 @@ StartupXLOG(void)
50755091ereport (LOG ,
50765092(errmsg ("database system was not properly shut down; "
50775093"automatic recovery in progress" )));
5094+ if (recoveryTargetTLI > 0 )
5095+ ereport (LOG ,
5096+ (errmsg ("crash recovery starts in timeline %u "
5097+ "and has target timeline %u" ,
5098+ ControlFile -> checkPointCopy .ThisTimeLineID ,
5099+ recoveryTargetTLI )));
50785100ControlFile -> state = DB_IN_CRASH_RECOVERY ;
50795101}
50805102ControlFile -> prevCheckPoint = ControlFile -> checkPoint ;
@@ -6945,6 +6967,7 @@ CreateEndOfRecoveryRecord(void)
69456967{
69466968xl_end_of_recovery xlrec ;
69476969XLogRecData rdata ;
6970+ XLogRecPtr recptr ;
69486971
69496972/* sanity check */
69506973if (!RecoveryInProgress ())
@@ -6962,7 +6985,20 @@ CreateEndOfRecoveryRecord(void)
69626985rdata .buffer = InvalidBuffer ;
69636986rdata .next = NULL ;
69646987
6965- (void )XLogInsert (RM_XLOG_ID ,XLOG_END_OF_RECOVERY ,& rdata );
6988+ recptr = XLogInsert (RM_XLOG_ID ,XLOG_END_OF_RECOVERY ,& rdata );
6989+
6990+ XLogFlush (recptr );
6991+
6992+ /*
6993+ * Update the control file so that crash recovery can follow
6994+ * the timeline changes to this point.
6995+ */
6996+ LWLockAcquire (ControlFileLock ,LW_EXCLUSIVE );
6997+ ControlFile -> time = (pg_time_t )xlrec .end_time ;
6998+ ControlFile -> minRecoveryPoint = recptr ;
6999+ ControlFile -> minRecoveryPointTLI = ThisTimeLineID ;
7000+ UpdateControlFile ();
7001+ LWLockRelease (ControlFileLock );
69667002
69677003END_CRIT_SECTION ();
69687004