@@ -4828,6 +4828,22 @@ StartupXLOG(void)
4828
4828
ereport (LOG ,
4829
4829
(errmsg ("starting archive recovery" )));
4830
4830
}
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
+ }
4831
4847
4832
4848
/*
4833
4849
* Take ownership of the wakeup latch if we're going to sleep during
@@ -5075,6 +5091,12 @@ StartupXLOG(void)
5075
5091
ereport (LOG ,
5076
5092
(errmsg ("database system was not properly shut down; "
5077
5093
"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 )));
5078
5100
ControlFile -> state = DB_IN_CRASH_RECOVERY ;
5079
5101
}
5080
5102
ControlFile -> prevCheckPoint = ControlFile -> checkPoint ;
@@ -6945,6 +6967,7 @@ CreateEndOfRecoveryRecord(void)
6945
6967
{
6946
6968
xl_end_of_recovery xlrec ;
6947
6969
XLogRecData rdata ;
6970
+ XLogRecPtr recptr ;
6948
6971
6949
6972
/* sanity check */
6950
6973
if (!RecoveryInProgress ())
@@ -6962,7 +6985,20 @@ CreateEndOfRecoveryRecord(void)
6962
6985
rdata .buffer = InvalidBuffer ;
6963
6986
rdata .next = NULL ;
6964
6987
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 );
6966
7002
6967
7003
END_CRIT_SECTION ();
6968
7004
0 commit comments