diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index 57ed8c8e29..e7e878c22f 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -45,6 +45,7 @@ typedef enum { POSTMASTER_READY, POSTMASTER_STILL_STARTING, + POSTMASTER_SHUTDOWN_IN_RECOVERY, POSTMASTER_FAILED, } WaitPMResult; @@ -657,17 +658,24 @@ wait_for_postmaster_start(pid_t pm_pid, bool do_checkpoint) * On Windows, we may be checking the postmaster's parent shell, but * that's fine for this purpose. */ -#ifndef WIN32 { + bool pm_died; +#ifndef WIN32 int exitstatus; - if (waitpid(pm_pid, &exitstatus, WNOHANG) == pm_pid) - return POSTMASTER_FAILED; - } + pm_died = (waitpid(pm_pid, &exitstatus, WNOHANG) == pm_pid); #else - if (WaitForSingleObject(postmasterProcess, 0) == WAIT_OBJECT_0) - return POSTMASTER_FAILED; + pm_died = (WaitForSingleObject(postmasterProcess, 0) == WAIT_OBJECT_0); #endif + if (pm_died) + { + /* See if postmaster terminated intentionally */ + if (get_control_dbstate() == DB_SHUTDOWNED_IN_RECOVERY) + return POSTMASTER_SHUTDOWN_IN_RECOVERY; + else + return POSTMASTER_FAILED; + } + } /* Startup still in process; wait, printing a dot once per second */ if (i % WAITS_PER_SEC == 0) @@ -991,6 +999,10 @@ do_start(void) progname); exit(1); break; + case POSTMASTER_SHUTDOWN_IN_RECOVERY: + print_msg(_(" done\n")); + print_msg(_("server shut down because of recovery target settings\n")); + break; case POSTMASTER_FAILED: print_msg(_(" stopped waiting\n")); write_stderr(_("%s: could not start server\n"