You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If backup-end record is not seen, and we reach end of recovery from a
streamed backup, throw an error and refuse to start up. The restore has not
finished correctly in that case and the data directory is possibly corrupt.
We already errored out in case of archive recovery, but could not during
crash recovery because we couldn't distinguish between the case that
pg_start_backup() was called and the database then crashed (must not error,
data is OK), and the case that we're restoring from a backup and not all
the needed WAL was replayed (data can be corrupt).
To distinguish those cases, add a line to backup_label to indicate
whether the backup was taken with pg_start/stop_backup(), or by streaming
(ie. pg_basebackup).
This is a different implementation than what I committed to 9.2 a week ago.
That implementation was not back-patchable because it required re-initdb.
Fujii Masao
* Read control file and check XLOG status looks valid.
@@ -6128,7 +6130,7 @@ StartupXLOG(void)
6128
6130
if (StandbyMode)
6129
6131
OwnLatch(&XLogCtl->recoveryWakeupLatch);
6130
6132
6131
-
if (read_backup_label(&checkPointLoc))
6133
+
if (read_backup_label(&checkPointLoc, &backupEndRequired))
6132
6134
{
6133
6135
/*
6134
6136
* When a backup_label file is present, we want to roll forward from
@@ -6304,10 +6306,17 @@ StartupXLOG(void)
6304
6306
}
6305
6307
6306
6308
/*
6307
-
* set backupStartPoint if we're starting recovery from a base backup
6309
+
* Set backupStartPoint if we're starting recovery from a base backup.
6310
+
* However, if there was no recovery.conf, and the backup was taken
6311
+
* with pg_start_backup(), we don't know if the server crashed before
6312
+
* the backup was finished and we're doing crash recovery on the
6313
+
* original server, or if we're restoring from the base backup. We
6314
+
* have to assume we're doing crash recovery in that case, or the
6315
+
* database would refuse to start up after a crash.
6308
6316
*/
6309
-
if (haveBackupLabel)
6317
+
if ((InArchiveRecovery&&haveBackupLabel) ||backupEndRequired)
6310
6318
ControlFile->backupStartPoint=checkPoint.redo;
6319
+
6311
6320
ControlFile->time= (pg_time_t) time(NULL);
6312
6321
/* No need to hold ControlFileLock yet, we aren't up far enough */
6313
6322
UpdateControlFile();
@@ -6670,23 +6679,15 @@ StartupXLOG(void)
6670
6679
6671
6680
/*
6672
6681
* Ran off end of WAL before reaching end-of-backup WAL record, or
6673
-
* minRecoveryPoint. That's usually a bad sign, indicating that you
6674
-
* tried to recover from an online backup but never called
6675
-
* pg_stop_backup(), or you didn't archive all the WAL up to that
6676
-
* point. However, this also happens in crash recovery, if the system
6677
-
* crashes while an online backup is in progress. We must not treat
6678
-
* that as an error, or the database will refuse to start up.
6682
+
* minRecoveryPoint.
6679
6683
*/
6680
-
if (InArchiveRecovery)
6681
-
{
6682
-
if (!XLogRecPtrIsInvalid(ControlFile->backupStartPoint))
6683
-
ereport(FATAL,
6684
-
(errmsg("WAL ends before end of online backup"),
6685
-
errhint("Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery.")));
6686
-
else
6687
-
ereport(FATAL,
6688
-
(errmsg("WAL ends before consistent recovery point")));
6689
-
}
6684
+
if (!XLogRecPtrIsInvalid(ControlFile->backupStartPoint))
6685
+
ereport(FATAL,
6686
+
(errmsg("WAL ends before end of online backup"),
6687
+
errhint("Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery.")));
6688
+
else
6689
+
ereport(FATAL,
6690
+
(errmsg("WAL ends before consistent recovery point")));
0 commit comments