Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Prevent starting a standalone backend with standby_mode on.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 31 Aug 2016 12:52:13 +0000 (08:52 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 31 Aug 2016 12:52:13 +0000 (08:52 -0400)
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

index acd95aa740817c0c44a5fe940a4b8bcf330c8ade..0b991bb91debbee4a6a336435999ebf54e4e0ec8 100644 (file)
@@ -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;