Skip to content

Commit 3d7905d

Browse files
committed
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.
1 parent 113082c commit 3d7905d

File tree

1 file changed

+17
-2
lines changed
  • src/backend/access/transam

1 file changed

+17
-2
lines changed

src/backend/access/transam/xlog.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5823,14 +5823,29 @@ StartupXLOG(void)
58235823
record = ReadCheckpointRecord(checkPointLoc, 0);
58245824
if (record != NULL)
58255825
{
5826+
memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
58265827
ereport(DEBUG1,
58275828
(errmsg("checkpoint record is at %X/%X",
58285829
checkPointLoc.xlogid, checkPointLoc.xrecoff)));
58295830
InRecovery = true; /* force recovery even if SHUTDOWNED */
5831+
5832+
/*
5833+
* Make sure that REDO location exists. This may not be
5834+
* the case if there was a crash during an online backup,
5835+
* which left a backup_label around that references a WAL
5836+
* segment that's already been archived.
5837+
*/
5838+
if (XLByteLT(checkPoint.redo, checkPointLoc))
5839+
{
5840+
if (!ReadRecord(&(checkPoint.redo), LOG, false))
5841+
ereport(FATAL,
5842+
(errmsg("could not find redo location referenced by checkpoint record"),
5843+
errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
5844+
}
58305845
}
58315846
else
58325847
{
5833-
ereport(PANIC,
5848+
ereport(FATAL,
58345849
(errmsg("could not locate required checkpoint record"),
58355850
errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
58365851
}
@@ -5876,10 +5891,10 @@ StartupXLOG(void)
58765891
ereport(PANIC,
58775892
(errmsg("could not locate a valid checkpoint record")));
58785893
}
5894+
memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
58795895
}
58805896

58815897
LastRec = RecPtr = checkPointLoc;
5882-
memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
58835898
wasShutdown = (record->xl_info == XLOG_CHECKPOINT_SHUTDOWN);
58845899

58855900
ereport(DEBUG1,

0 commit comments

Comments
 (0)