1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-07 11:02:12 +03:00

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>
This commit is contained in:
Tom Lane 2016-08-31 08:52:13 -04:00
parent 5833306dd6
commit baf111d31b

View File

@ -4220,7 +4220,8 @@ readRecoveryCommandFile(void)
rtli = (TimeLineID) strtoul(item->value, NULL, 0); rtli = (TimeLineID) strtoul(item->value, NULL, 0);
if (errno == EINVAL || errno == ERANGE) if (errno == EINVAL || errno == ERANGE)
ereport(FATAL, 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))); item->value)));
} }
if (rtli) if (rtli)
@ -4236,7 +4237,8 @@ readRecoveryCommandFile(void)
recoveryTargetXid = (TransactionId) strtoul(item->value, NULL, 0); recoveryTargetXid = (TransactionId) strtoul(item->value, NULL, 0);
if (errno == EINVAL || errno == ERANGE) if (errno == EINVAL || errno == ERANGE)
ereport(FATAL, 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))); item->value)));
ereport(DEBUG2, ereport(DEBUG2,
(errmsg_internal("recovery_target_xid = %u", (errmsg_internal("recovery_target_xid = %u",
@ -4327,7 +4329,8 @@ readRecoveryCommandFile(void)
} }
else else
ereport(FATAL, ereport(FATAL,
(errmsg("unrecognized recovery parameter \"%s\"", (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized recovery parameter \"%s\"",
item->name))); item->name)));
} }
@ -4346,10 +4349,20 @@ readRecoveryCommandFile(void)
{ {
if (recoveryRestoreCommand == NULL) if (recoveryRestoreCommand == NULL)
ereport(FATAL, 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))); RECOVERY_COMMAND_FILE)));
} }
/*
* 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 */ /* Enable fetching from archive recovery area */
ArchiveRecoveryRequested = true; ArchiveRecoveryRequested = true;
@ -4366,7 +4379,8 @@ readRecoveryCommandFile(void)
/* Timeline 1 does not have a history file, all else should */ /* Timeline 1 does not have a history file, all else should */
if (rtli != 1 && !existsTimeLineHistory(rtli)) if (rtli != 1 && !existsTimeLineHistory(rtli))
ereport(FATAL, ereport(FATAL,
(errmsg("recovery target timeline %u does not exist", (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("recovery target timeline %u does not exist",
rtli))); rtli)));
recoveryTargetTLI = rtli; recoveryTargetTLI = rtli;
recoveryTargetIsLatest = false; recoveryTargetIsLatest = false;