Commit 0c6293dd authored by Heikki Linnakangas's avatar Heikki Linnakangas

Before removing backup_label and irrevocably changing pg_control file, check

that WAL file containing the checkpoint redo-location can be found. This
avoids making the cluster irrecoverable if the redo location is in an earlie
WAL file than the checkpoint record.

Report, analysis and patch by Jeff Davis, with small changes by me.
parent a87d2126
...@@ -5839,14 +5839,29 @@ StartupXLOG(void) ...@@ -5839,14 +5839,29 @@ StartupXLOG(void)
record = ReadCheckpointRecord(checkPointLoc, 0); record = ReadCheckpointRecord(checkPointLoc, 0);
if (record != NULL) if (record != NULL)
{ {
memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
ereport(DEBUG1, ereport(DEBUG1,
(errmsg("checkpoint record is at %X/%X", (errmsg("checkpoint record is at %X/%X",
checkPointLoc.xlogid, checkPointLoc.xrecoff))); checkPointLoc.xlogid, checkPointLoc.xrecoff)));
InRecovery = true; /* force recovery even if SHUTDOWNED */ InRecovery = true; /* force recovery even if SHUTDOWNED */
/*
* Make sure that REDO location exists. This may not be
* the case if there was a crash during an online backup,
* which left a backup_label around that references a WAL
* segment that's already been archived.
*/
if (XLByteLT(checkPoint.redo, checkPointLoc))
{
if (!ReadRecord(&(checkPoint.redo), LOG, false))
ereport(FATAL,
(errmsg("could not find redo location referenced by checkpoint record"),
errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
}
} }
else else
{ {
ereport(PANIC, ereport(FATAL,
(errmsg("could not locate required checkpoint record"), (errmsg("could not locate required checkpoint record"),
errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir))); errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
} }
...@@ -5892,10 +5907,10 @@ StartupXLOG(void) ...@@ -5892,10 +5907,10 @@ StartupXLOG(void)
ereport(PANIC, ereport(PANIC,
(errmsg("could not locate a valid checkpoint record"))); (errmsg("could not locate a valid checkpoint record")));
} }
memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
} }
LastRec = RecPtr = checkPointLoc; LastRec = RecPtr = checkPointLoc;
memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
wasShutdown = (record->xl_info == XLOG_CHECKPOINT_SHUTDOWN); wasShutdown = (record->xl_info == XLOG_CHECKPOINT_SHUTDOWN);
ereport(DEBUG1, ereport(DEBUG1,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment