Skip to content

Commit baf111d

Browse files
committed
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>
1 parent 5833306 commit baf111d

File tree

1 file changed

+19
-5
lines changed
  • src/backend/access/transam

1 file changed

+19
-5
lines changed

src/backend/access/transam/xlog.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4220,7 +4220,8 @@ readRecoveryCommandFile(void)
42204220
rtli = (TimeLineID) strtoul(item->value, NULL, 0);
42214221
if (errno == EINVAL || errno == ERANGE)
42224222
ereport(FATAL,
4223-
(errmsg("recovery_target_timeline is not a valid number: \"%s\"",
4223+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4224+
errmsg("recovery_target_timeline is not a valid number: \"%s\"",
42244225
item->value)));
42254226
}
42264227
if (rtli)
@@ -4236,7 +4237,8 @@ readRecoveryCommandFile(void)
42364237
recoveryTargetXid = (TransactionId) strtoul(item->value, NULL, 0);
42374238
if (errno == EINVAL || errno == ERANGE)
42384239
ereport(FATAL,
4239-
(errmsg("recovery_target_xid is not a valid number: \"%s\"",
4240+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4241+
errmsg("recovery_target_xid is not a valid number: \"%s\"",
42404242
item->value)));
42414243
ereport(DEBUG2,
42424244
(errmsg_internal("recovery_target_xid = %u",
@@ -4327,7 +4329,8 @@ readRecoveryCommandFile(void)
43274329
}
43284330
else
43294331
ereport(FATAL,
4330-
(errmsg("unrecognized recovery parameter \"%s\"",
4332+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4333+
errmsg("unrecognized recovery parameter \"%s\"",
43314334
item->name)));
43324335
}
43334336

@@ -4346,10 +4349,20 @@ readRecoveryCommandFile(void)
43464349
{
43474350
if (recoveryRestoreCommand == NULL)
43484351
ereport(FATAL,
4349-
(errmsg("recovery command file \"%s\" must specify restore_command when standby mode is not enabled",
4352+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4353+
errmsg("recovery command file \"%s\" must specify restore_command when standby mode is not enabled",
43504354
RECOVERY_COMMAND_FILE)));
43514355
}
43524356

4357+
/*
4358+
* We don't support standby_mode in standalone backends; that requires
4359+
* other processes such as the WAL receiver to be alive.
4360+
*/
4361+
if (StandbyModeRequested && !IsUnderPostmaster)
4362+
ereport(FATAL,
4363+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4364+
errmsg("standby mode is not supported by single-user servers")));
4365+
43534366
/* Enable fetching from archive recovery area */
43544367
ArchiveRecoveryRequested = true;
43554368

@@ -4366,7 +4379,8 @@ readRecoveryCommandFile(void)
43664379
/* Timeline 1 does not have a history file, all else should */
43674380
if (rtli != 1 && !existsTimeLineHistory(rtli))
43684381
ereport(FATAL,
4369-
(errmsg("recovery target timeline %u does not exist",
4382+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4383+
errmsg("recovery target timeline %u does not exist",
43704384
rtli)));
43714385
recoveryTargetTLI = rtli;
43724386
recoveryTargetIsLatest = false;

0 commit comments

Comments
 (0)