From 0e0f43d6fdc2e1fbd5261245ed4cf85302a3f653 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 31 Aug 2016 08:52:13 -0400 Subject: [PATCH] Prevent starting a standalone backend with standby_mode on. This can't really work because standby_mode expects there to be more WAL arriving, which there will not ever be because there's no WAL receiver process to fetch it. Moreover, if standby_mode is on then hot standby might also be turned on, causing even more strangeness because that expects read-only sessions to be executing in parallel. Bernd Helmle reported a case where btree_xlog_delete_get_latestRemovedXid got confused, but rather than band-aiding individual problems it seems best to prevent getting anywhere near this state in the first place. Back-patch to all supported branches. In passing, also fix some omissions of errcodes in other ereport's in readRecoveryCommandFile(). Michael Paquier (errcode hacking by me) Discussion: <00F0B2CEF6D0CEF8A90119D4@eje.credativ.lan> --- src/backend/access/transam/xlog.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index acd95aa740..0b991bb91d 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -5022,7 +5022,8 @@ readRecoveryCommandFile(void) rtli = (TimeLineID) strtoul(item->value, NULL, 0); if (errno == EINVAL || errno == ERANGE) ereport(FATAL, - (errmsg("recovery_target_timeline is not a valid number: \"%s\"", + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("recovery_target_timeline is not a valid number: \"%s\"", item->value))); } if (rtli) @@ -5038,7 +5039,8 @@ readRecoveryCommandFile(void) recoveryTargetXid = (TransactionId) strtoul(item->value, NULL, 0); if (errno == EINVAL || errno == ERANGE) ereport(FATAL, - (errmsg("recovery_target_xid is not a valid number: \"%s\"", + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("recovery_target_xid is not a valid number: \"%s\"", item->value))); ereport(DEBUG2, (errmsg_internal("recovery_target_xid = %u", @@ -5153,7 +5155,8 @@ readRecoveryCommandFile(void) } else ereport(FATAL, - (errmsg("unrecognized recovery parameter \"%s\"", + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("unrecognized recovery parameter \"%s\"", item->name))); } @@ -5172,7 +5175,8 @@ readRecoveryCommandFile(void) { if (recoveryRestoreCommand == NULL) ereport(FATAL, - (errmsg("recovery command file \"%s\" must specify restore_command when standby mode is not enabled", + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("recovery command file \"%s\" must specify restore_command when standby mode is not enabled", RECOVERY_COMMAND_FILE))); } @@ -5186,6 +5190,15 @@ readRecoveryCommandFile(void) !EnableHotStandby) recoveryTargetAction = RECOVERY_TARGET_ACTION_SHUTDOWN; + /* + * We don't support standby_mode in standalone backends; that requires + * other processes such as the WAL receiver to be alive. + */ + if (StandbyModeRequested && !IsUnderPostmaster) + ereport(FATAL, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("standby mode is not supported by single-user servers"))); + /* Enable fetching from archive recovery area */ ArchiveRecoveryRequested = true; @@ -5202,7 +5215,8 @@ readRecoveryCommandFile(void) /* Timeline 1 does not have a history file, all else should */ if (rtli != 1 && !existsTimeLineHistory(rtli)) ereport(FATAL, - (errmsg("recovery target timeline %u does not exist", + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("recovery target timeline %u does not exist", rtli))); recoveryTargetTLI = rtli; recoveryTargetIsLatest = false;