Skip to content

Commit ce08325

Browse files
committed
Fix (re-)starting from a basebackup taken off a standby after a failure.
When starting up from a basebackup taken off a standby extra logic has to be applied to compute the point where the data directory is consistent. Normal base backups use a WAL record for that purpose, but that isn't possible on a standby. That logic had a error check ensuring that the cluster's control file indicates being in recovery. Unfortunately that check was too strict, disregarding the fact that the control file could also indicate that the cluster was shut down while in recovery. That's possible when the a cluster starting from a basebackup is shut down before the backup label has been removed. When everything goes well that's a short window, but when either restore_command or primary_conninfo isn't configured correctly the window can get much wider. That's because inbetween reading and unlinking the label we restore the last checkpoint from WAL which can need additional WAL. To fix simply also allow starting when the control file indicates "shutdown in recovery". There's nicer fixes imaginable, but they'd be more invasive. Backpatch to 9.2 where support for taking basebackups from standbys was added.
1 parent e35e76a commit ce08325

File tree

1 file changed

+12
-5
lines changed
  • src/backend/access/transam

1 file changed

+12
-5
lines changed

src/backend/access/transam/xlog.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6445,11 +6445,17 @@ StartupXLOG(void)
64456445
/*
64466446
* Set backupStartPoint if we're starting recovery from a base backup.
64476447
*
6448-
* Set backupEndPoint and use minRecoveryPoint as the backup end
6448+
* Also set backupEndPoint and use minRecoveryPoint as the backup end
64496449
* location if we're starting recovery from a base backup which was
6450-
* taken from the standby. In this case, the database system status in
6451-
* pg_control must indicate DB_IN_ARCHIVE_RECOVERY. If not, which
6452-
* means that backup is corrupted, so we cancel recovery.
6450+
* taken from a standby. In this case, the database system status in
6451+
* pg_control must indicate that the database was already in
6452+
* recovery. Usually that will be DB_IN_ARCHIVE_RECOVERY but also can
6453+
* be DB_SHUTDOWNED_IN_RECOVERY if recovery previously was interrupted
6454+
* before reaching this point; e.g. because restore_command or
6455+
* primary_conninfo were faulty.
6456+
*
6457+
* Any other state indicates that the backup somehow became corrupted
6458+
* and we can't sensibly continue with recovery.
64536459
*/
64546460
if (haveBackupLabel)
64556461
{
@@ -6458,7 +6464,8 @@ StartupXLOG(void)
64586464

64596465
if (backupFromStandby)
64606466
{
6461-
if (dbstate_at_startup != DB_IN_ARCHIVE_RECOVERY)
6467+
if (dbstate_at_startup != DB_IN_ARCHIVE_RECOVERY &&
6468+
dbstate_at_startup != DB_SHUTDOWNED_IN_RECOVERY)
64626469
ereport(FATAL,
64636470
(errmsg("backup_label contains data inconsistent with control file"),
64646471
errhint("This means that the backup is corrupted and you will "

0 commit comments

Comments
 (0)