From b85e43feb3e837699239aba6b8e0f280a59417be Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 8 Nov 2019 08:03:16 +0100 Subject: [PATCH] More precise errors from initial pg_control check Use a separate error message for invalid checkpoint location and invalid state instead of just "invalid data" for both. Reviewed-by: Michael Paquier Discussion: https://www.postgresql.org/message-id/20191107041630.GK1768@paquier.xyz --- src/backend/access/transam/xlog.c | 82 ++++++++++++++++++------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 2e3cc51006..55d01a86c7 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -6231,45 +6231,59 @@ StartupXLOG(void) CurrentResourceOwner = AuxProcessResourceOwner; /* - * Verify XLOG status looks valid. + * Check that contents look valid. */ - if (ControlFile->state < DB_SHUTDOWNED || - ControlFile->state > DB_IN_PRODUCTION || - !XRecOffIsValid(ControlFile->checkPoint)) + if (!XRecOffIsValid(ControlFile->checkPoint)) ereport(FATAL, - (errmsg("control file contains invalid data"))); + (errmsg("control file contains invalid checkpoint location"))); - if (ControlFile->state == DB_SHUTDOWNED) + switch (ControlFile->state) { - /* This is the expected case, so don't be chatty in standalone mode */ - ereport(IsPostmasterEnvironment ? LOG : NOTICE, - (errmsg("database system was shut down at %s", - str_time(ControlFile->time)))); + case DB_SHUTDOWNED: + /* This is the expected case, so don't be chatty in standalone mode */ + ereport(IsPostmasterEnvironment ? LOG : NOTICE, + (errmsg("database system was shut down at %s", + str_time(ControlFile->time)))); + break; + + case DB_SHUTDOWNED_IN_RECOVERY: + ereport(LOG, + (errmsg("database system was shut down in recovery at %s", + str_time(ControlFile->time)))); + break; + + case DB_SHUTDOWNING: + ereport(LOG, + (errmsg("database system shutdown was interrupted; last known up at %s", + str_time(ControlFile->time)))); + break; + + case DB_IN_CRASH_RECOVERY: + ereport(LOG, + (errmsg("database system was interrupted while in recovery at %s", + str_time(ControlFile->time)), + errhint("This probably means that some data is corrupted and" + " you will have to use the last backup for recovery."))); + break; + + case DB_IN_ARCHIVE_RECOVERY: + ereport(LOG, + (errmsg("database system was interrupted while in recovery at log time %s", + str_time(ControlFile->checkPointCopy.time)), + errhint("If this has occurred more than once some data might be corrupted" + " and you might need to choose an earlier recovery target."))); + break; + + case DB_IN_PRODUCTION: + ereport(LOG, + (errmsg("database system was interrupted; last known up at %s", + str_time(ControlFile->time)))); + break; + + default: + ereport(FATAL, + (errmsg("control file contains invalid database cluster state"))); } - else if (ControlFile->state == DB_SHUTDOWNED_IN_RECOVERY) - ereport(LOG, - (errmsg("database system was shut down in recovery at %s", - str_time(ControlFile->time)))); - else if (ControlFile->state == DB_SHUTDOWNING) - ereport(LOG, - (errmsg("database system shutdown was interrupted; last known up at %s", - str_time(ControlFile->time)))); - else if (ControlFile->state == DB_IN_CRASH_RECOVERY) - ereport(LOG, - (errmsg("database system was interrupted while in recovery at %s", - str_time(ControlFile->time)), - errhint("This probably means that some data is corrupted and" - " you will have to use the last backup for recovery."))); - else if (ControlFile->state == DB_IN_ARCHIVE_RECOVERY) - ereport(LOG, - (errmsg("database system was interrupted while in recovery at log time %s", - str_time(ControlFile->checkPointCopy.time)), - errhint("If this has occurred more than once some data might be corrupted" - " and you might need to choose an earlier recovery target."))); - else if (ControlFile->state == DB_IN_PRODUCTION) - ereport(LOG, - (errmsg("database system was interrupted; last known up at %s", - str_time(ControlFile->time)))); /* This is just to allow attaching to startup process with a debugger */ #ifdef XLOG_REPLAY_DELAY