#define BACKEND_TYPE_BGWORKER  0x0008  /* bgworker process */
 #define BACKEND_TYPE_ALL       0x000F  /* OR of all the above */
 
-#define BACKEND_TYPE_WORKER        (BACKEND_TYPE_AUTOVAC | BACKEND_TYPE_BGWORKER)
-
 /*
  * List of active backends (or child processes anyway; we don't actually
  * know whether a given child has become a backend or is still in the
  * and we switch to PM_RUN state.
  *
  * Normal child backends can only be launched when we are in PM_RUN or
- * PM_HOT_STANDBY state.  (We also allow launch of normal
- * child backends in PM_WAIT_BACKUP state, but only for superusers.)
+ * PM_HOT_STANDBY state.  (connsAllowed can also restrict launching.)
  * In other states we handle connection requests by launching "dead_end"
  * child processes, which will simply send the client an error message and
  * quit.  (We track these in the BackendList so that we can know when they
  *
  * Notice that this state variable does not distinguish *why* we entered
  * states later than PM_RUN --- Shutdown and FatalError must be consulted
- * to find that out.  FatalError is never true in PM_RECOVERY_* or PM_RUN
- * states, nor in PM_SHUTDOWN states (because we don't enter those states
- * when trying to recover from a crash).  It can be true in PM_STARTUP state,
- * because we don't clear it until we've successfully started WAL redo.
+ * to find that out.  FatalError is never true in PM_RECOVERY, PM_HOT_STANDBY,
+ * or PM_RUN states, nor in PM_SHUTDOWN states (because we don't enter those
+ * states when trying to recover from a crash).  It can be true in PM_STARTUP
+ * state, because we don't clear it until we've successfully started WAL redo.
  */
 typedef enum
 {
    PM_RECOVERY,                /* in archive recovery mode */
    PM_HOT_STANDBY,             /* in hot standby mode */
    PM_RUN,                     /* normal "database is alive" state */
-   PM_WAIT_BACKUP,             /* waiting for online backup mode to end */
-   PM_WAIT_READONLY,           /* waiting for read only backends to exit */
+   PM_STOP_BACKENDS,           /* need to stop remaining backends */
    PM_WAIT_BACKENDS,           /* waiting for live backends to exit */
    PM_SHUTDOWN,                /* waiting for checkpointer to do shutdown
                                 * ckpt */
 
 static PMState pmState = PM_INIT;
 
+/*
+ * While performing a "smart shutdown", we restrict new connections but stay
+ * in PM_RUN or PM_HOT_STANDBY state until all the client backends are gone.
+ * connsAllowed is a sub-state indicator showing the active restriction.
+ * It is of no interest unless pmState is PM_RUN or PM_HOT_STANDBY.
+ */
+typedef enum
+{
+   ALLOW_ALL_CONNS,            /* normal not-shutting-down state */
+   ALLOW_SUPERUSER_CONNS,      /* only superusers can connect */
+   ALLOW_NO_CONNS              /* no new connections allowed, period */
+} ConnsAllowedState;
+
+static ConnsAllowedState connsAllowed = ALLOW_ALL_CONNS;
+
 /* Start time of SIGKILL timeout during immediate shutdown or child crash */
 /* Zero means timeout is not running */
 static time_t AbortStartTime = 0;
                    (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
                     errmsg("sorry, too many clients already")));
            break;
-       case CAC_WAITBACKUP:
+       case CAC_SUPERUSER:
            /* OK for now, will check in InitPostgres */
            break;
        case CAC_OK:
     * state.  We treat autovac workers the same as user backends for this
     * purpose.  However, bgworkers are excluded from this test; we expect
     * bgworker_should_start_now() decided whether the DB state allows them.
-    *
-    * In state PM_WAIT_BACKUP only superusers can connect (this must be
-    * allowed so that a superuser can end online backup mode); we return
-    * CAC_WAITBACKUP code to indicate that this must be checked later. Note
-    * that neither CAC_OK nor CAC_WAITBACKUP can safely be returned until we
-    * have checked for too many children.
     */
-   if (pmState != PM_RUN &&
+   if (pmState != PM_RUN && pmState != PM_HOT_STANDBY &&
        backend_type != BACKEND_TYPE_BGWORKER)
    {
-       if (pmState == PM_WAIT_BACKUP)
-           result = CAC_WAITBACKUP;    /* allow superusers only */
-       else if (Shutdown > NoShutdown)
+       if (Shutdown > NoShutdown)
            return CAC_SHUTDOWN;    /* shutdown is pending */
        else if (!FatalError &&
                 (pmState == PM_STARTUP ||
                  pmState == PM_RECOVERY))
            return CAC_STARTUP; /* normal startup */
-       else if (!FatalError &&
-                pmState == PM_HOT_STANDBY)
-           result = CAC_OK;    /* connection OK during hot standby */
        else
            return CAC_RECOVERY;    /* else must be crash recovery */
    }
 
+   /*
+    * "Smart shutdown" restrictions are applied only to normal connections,
+    * not to autovac workers or bgworkers.  When only superusers can connect,
+    * we return CAC_SUPERUSER to indicate that superuserness must be checked
+    * later.  Note that neither CAC_OK nor CAC_SUPERUSER can safely be
+    * returned until we have checked for too many children.
+    */
+   if (connsAllowed != ALLOW_ALL_CONNS &&
+       backend_type == BACKEND_TYPE_NORMAL)
+   {
+       if (connsAllowed == ALLOW_SUPERUSER_CONNS)
+           result = CAC_SUPERUSER; /* allow superusers only */
+       else
+           return CAC_SHUTDOWN;    /* shutdown is pending */
+   }
+
    /*
     * Don't start too many children.
     *
            sd_notify(0, "STOPPING=1");
 #endif
 
-           if (pmState == PM_RUN || pmState == PM_RECOVERY ||
-               pmState == PM_HOT_STANDBY || pmState == PM_STARTUP)
+           /*
+            * If we reached normal running, we have to wait for any online
+            * backup mode to end; otherwise go straight to waiting for client
+            * backends to exit.  (The difference is that in the former state,
+            * we'll still let in new superuser clients, so that somebody can
+            * end the online backup mode.)  If already in PM_STOP_BACKENDS or
+            * a later state, do not change it.
+            */
+           if (pmState == PM_RUN)
+               connsAllowed = ALLOW_SUPERUSER_CONNS;
+           else if (pmState == PM_HOT_STANDBY)
+               connsAllowed = ALLOW_NO_CONNS;
+           else if (pmState == PM_STARTUP || pmState == PM_RECOVERY)
            {
-               /* autovac workers are told to shut down immediately */
-               /* and bgworkers too; does this need tweaking? */
-               SignalSomeChildren(SIGTERM,
-                              BACKEND_TYPE_AUTOVAC | BACKEND_TYPE_BGWORKER);
-               /* and the autovac launcher too */
-               if (AutoVacPID != 0)
-                   signal_child(AutoVacPID, SIGTERM);
-               /* and the bgwriter too */
-               if (BgWriterPID != 0)
-                   signal_child(BgWriterPID, SIGTERM);
-               /* and the walwriter too */
-               if (WalWriterPID != 0)
-                   signal_child(WalWriterPID, SIGTERM);
-
-               /*
-                * If we're in recovery, we can't kill the startup process
-                * right away, because at present doing so does not release
-                * its locks.  We might want to change this in a future
-                * release.  For the time being, the PM_WAIT_READONLY state
-                * indicates that we're waiting for the regular (read only)
-                * backends to die off; once they do, we'll kill the startup
-                * and walreceiver processes.
-                */
-               pmState = (pmState == PM_RUN) ?
-                   PM_WAIT_BACKUP : PM_WAIT_READONLY;
+               /* There should be no clients, so proceed to stop children */
+               pmState = PM_STOP_BACKENDS;
            }
 
            /*
            sd_notify(0, "STOPPING=1");
 #endif
 
-           if (StartupPID != 0)
-               signal_child(StartupPID, SIGTERM);
-           if (BgWriterPID != 0)
-               signal_child(BgWriterPID, SIGTERM);
-           if (WalReceiverPID != 0)
-               signal_child(WalReceiverPID, SIGTERM);
            if (pmState == PM_STARTUP || pmState == PM_RECOVERY)
            {
-               SignalSomeChildren(SIGTERM, BACKEND_TYPE_BGWORKER);
-
-               /*
-                * Only startup, bgwriter, walreceiver, possibly bgworkers,
-                * and/or checkpointer should be active in this state; we just
-                * signaled the first four, and we don't want to kill
-                * checkpointer yet.
-                */
-               pmState = PM_WAIT_BACKENDS;
+               /* Just shut down background processes silently */
+               pmState = PM_STOP_BACKENDS;
            }
            else if (pmState == PM_RUN ||
-                    pmState == PM_WAIT_BACKUP ||
-                    pmState == PM_WAIT_READONLY ||
-                    pmState == PM_WAIT_BACKENDS ||
                     pmState == PM_HOT_STANDBY)
            {
+               /* Report that we're about to zap live client sessions */
                ereport(LOG,
                        (errmsg("aborting any active transactions")));
-               /* shut down all backends and workers */
-               SignalSomeChildren(SIGTERM,
-                                BACKEND_TYPE_NORMAL | BACKEND_TYPE_AUTOVAC |
-                                  BACKEND_TYPE_BGWORKER);
-               /* and the autovac launcher too */
-               if (AutoVacPID != 0)
-                   signal_child(AutoVacPID, SIGTERM);
-               /* and the walwriter too */
-               if (WalWriterPID != 0)
-                   signal_child(WalWriterPID, SIGTERM);
-               pmState = PM_WAIT_BACKENDS;
+               pmState = PM_STOP_BACKENDS;
            }
 
            /*
-            * Now wait for backends to exit.  If there are none,
-            * PostmasterStateMachine will take the next step.
+            * PostmasterStateMachine will issue any necessary signals, or
+            * take the next step if no child processes need to be killed.
             */
            PostmasterStateMachine();
            break;
                ereport(LOG,
                        (errmsg("shutdown at recovery target")));
                StartupStatus = STARTUP_NOT_RUNNING;
-               Shutdown = SmartShutdown;
+               Shutdown = Max(Shutdown, SmartShutdown);
                TerminateChildren(SIGTERM);
                pmState = PM_WAIT_BACKENDS;
                /* PostmasterStateMachine logic does the rest */
            Assert(AbortStartTime == 0);
            ReachedNormalRunning = true;
            pmState = PM_RUN;
+           connsAllowed = ALLOW_ALL_CONNS;
 
            /*
             * Crank up the background tasks, if we didn't do that already
    if (pmState == PM_RECOVERY ||
        pmState == PM_HOT_STANDBY ||
        pmState == PM_RUN ||
-       pmState == PM_WAIT_BACKUP ||
-       pmState == PM_WAIT_READONLY ||
+       pmState == PM_STOP_BACKENDS ||
        pmState == PM_SHUTDOWN)
        pmState = PM_WAIT_BACKENDS;
 
 static void
 PostmasterStateMachine(void)
 {
-   if (pmState == PM_WAIT_BACKUP)
+   /* If we're doing a smart shutdown, try to advance that state. */
+   if (pmState == PM_RUN || pmState == PM_HOT_STANDBY)
    {
-       /*
-        * PM_WAIT_BACKUP state ends when online backup mode is not active.
-        */
-       if (!BackupInProgress())
-           pmState = PM_WAIT_BACKENDS;
-   }
+       if (connsAllowed == ALLOW_SUPERUSER_CONNS)
+       {
+           /*
+            * ALLOW_SUPERUSER_CONNS state ends as soon as online backup mode
+            * is not active.
+            */
+           if (!BackupInProgress())
+               connsAllowed = ALLOW_NO_CONNS;
+       }
 
-   if (pmState == PM_WAIT_READONLY)
-   {
-       /*
-        * PM_WAIT_READONLY state ends when we have no regular backends that
-        * have been started during recovery.  We kill the startup and
-        * walreceiver processes and transition to PM_WAIT_BACKENDS.  Ideally,
-        * we might like to kill these processes first and then wait for
-        * backends to die off, but that doesn't work at present because
-        * killing the startup process doesn't release its locks.
-        */
-       if (CountChildren(BACKEND_TYPE_NORMAL) == 0)
+       if (connsAllowed == ALLOW_NO_CONNS)
        {
-           if (StartupPID != 0)
-               signal_child(StartupPID, SIGTERM);
-           if (WalReceiverPID != 0)
-               signal_child(WalReceiverPID, SIGTERM);
-           pmState = PM_WAIT_BACKENDS;
+           /*
+            * ALLOW_NO_CONNS state ends when we have no normal client
+            * backends running.  Then we're ready to stop other children.
+            */
+           if (CountChildren(BACKEND_TYPE_NORMAL) == 0)
+               pmState = PM_STOP_BACKENDS;
        }
    }
 
+   /*
+    * If we're ready to do so, signal child processes to shut down.  (This
+    * isn't a persistent state, but treating it as a distinct pmState allows
+    * us to share this code across multiple shutdown code paths.)
+    */
+   if (pmState == PM_STOP_BACKENDS)
+   {
+       /* Signal all backend children except walsenders */
+       SignalSomeChildren(SIGTERM,
+                          BACKEND_TYPE_ALL - BACKEND_TYPE_WALSND);
+       /* and the autovac launcher too */
+       if (AutoVacPID != 0)
+           signal_child(AutoVacPID, SIGTERM);
+       /* and the bgwriter too */
+       if (BgWriterPID != 0)
+           signal_child(BgWriterPID, SIGTERM);
+       /* and the walwriter too */
+       if (WalWriterPID != 0)
+           signal_child(WalWriterPID, SIGTERM);
+       /* If we're in recovery, also stop startup and walreceiver procs */
+       if (StartupPID != 0)
+           signal_child(StartupPID, SIGTERM);
+       if (WalReceiverPID != 0)
+           signal_child(WalReceiverPID, SIGTERM);
+       /* checkpointer, archiver, stats, and syslogger may continue for now */
+
+       /* Now transition to PM_WAIT_BACKENDS state to wait for them to die */
+       pmState = PM_WAIT_BACKENDS;
+   }
+
    /*
     * If we are in a state-machine state that implies waiting for backends to
     * exit, see if they're all gone, and change state if so.
         * later after writing the checkpoint record, like the archiver
         * process.
         */
-       if (CountChildren(BACKEND_TYPE_NORMAL | BACKEND_TYPE_WORKER) == 0 &&
+       if (CountChildren(BACKEND_TYPE_ALL - BACKEND_TYPE_WALSND) == 0 &&
            StartupPID == 0 &&
            WalReceiverPID == 0 &&
            BgWriterPID == 0 &&
    /* Pass down canAcceptConnections state */
    port->canAcceptConnections = canAcceptConnections(BACKEND_TYPE_NORMAL);
    bn->dead_end = (port->canAcceptConnections != CAC_OK &&
-                   port->canAcceptConnections != CAC_WAITBACKUP);
+                   port->canAcceptConnections != CAC_SUPERUSER);
 
    /*
     * Unless it's a dead_end child, assign it a child slot number
 #endif
 
        pmState = PM_HOT_STANDBY;
+       connsAllowed = ALLOW_ALL_CONNS;
+
        /* Some workers may be scheduled to start now */
        StartWorkerNeeded = true;
    }
    }
 
    if (CheckPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER) &&
-       Shutdown == NoShutdown)
+       Shutdown <= SmartShutdown && pmState < PM_STOP_BACKENDS)
    {
        /*
         * Start one iteration of the autovacuum daemon, even if autovacuuming
    }
 
    if (CheckPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER) &&
-       Shutdown == NoShutdown)
+       Shutdown <= SmartShutdown && pmState < PM_STOP_BACKENDS)
    {
        /* The autovacuum launcher wants us to start a worker process. */
        StartAutovacuumWorker();
 
    if (StartupPID != 0 &&
        (pmState == PM_STARTUP || pmState == PM_RECOVERY ||
-        pmState == PM_HOT_STANDBY || pmState == PM_WAIT_READONLY) &&
+        pmState == PM_HOT_STANDBY) &&
        CheckPromoteSignal())
    {
        /* Tell startup process to finish recovery */
 {
    if (WalReceiverPID == 0 &&
        (pmState == PM_STARTUP || pmState == PM_RECOVERY ||
-        pmState == PM_HOT_STANDBY || pmState == PM_WAIT_READONLY) &&
-       Shutdown == NoShutdown)
+        pmState == PM_HOT_STANDBY) &&
+       Shutdown <= SmartShutdown)
    {
        WalReceiverPID = StartWalReceiver();
        if (WalReceiverPID != 0)
        case PM_SHUTDOWN_2:
        case PM_SHUTDOWN:
        case PM_WAIT_BACKENDS:
-       case PM_WAIT_READONLY:
-       case PM_WAIT_BACKUP:
+       case PM_STOP_BACKENDS:
            break;
 
        case PM_RUN: