aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2010-10-26 21:15:42 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2010-10-26 21:41:49 +0300
commitb7888758d85f77388ca0ffd26ee37655e90d695c (patch)
tree894068780c6005a97164af81b319ea954c616257
parent4a75c7f9f1120db240b4ddccaa7d46f82bb495c0 (diff)
downloadpostgresql-b7888758d85f77388ca0ffd26ee37655e90d695c.tar.gz
postgresql-b7888758d85f77388ca0ffd26ee37655e90d695c.zip
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.
-rw-r--r--src/backend/access/transam/xlog.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 27683452eaa..698434cc5e8 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -5323,14 +5323,29 @@ StartupXLOG(void)
record = ReadCheckpointRecord(checkPointLoc, 0);
if (record != NULL)
{
+ memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
ereport(DEBUG1,
(errmsg("checkpoint record is at %X/%X",
checkPointLoc.xlogid, checkPointLoc.xrecoff)));
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))
+ 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
{
- ereport(PANIC,
+ ereport(FATAL,
(errmsg("could not locate required checkpoint record"),
errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir)));
}
@@ -5366,10 +5381,10 @@ StartupXLOG(void)
ereport(PANIC,
(errmsg("could not locate a valid checkpoint record")));
}
+ memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
}
LastRec = RecPtr = checkPointLoc;
- memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint));
wasShutdown = (record->xl_info == XLOG_CHECKPOINT_SHUTDOWN);
ereport(DEBUG1,