From 7e784d1dc191be24480a6b31a4ddc8e0e52be24d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 24 Dec 2020 12:58:32 -0500 Subject: Improve client error messages for immediate-stop situations. Up to now, if the DBA issued "pg_ctl stop -m immediate", the message sent to clients was the same as for a crash-and-restart situation. This is confusing, not least because the message claims that the database will soon be up again, something we have no business predicting. Improve things so that we can generate distinct messages for the two cases (and also recognize an ad-hoc SIGQUIT, should somebody try that). To do that, add a field to pmsignal.c's shared memory data structure that the postmaster sets just before broadcasting SIGQUIT to its children. No interlocking seems to be necessary; the intervening signal-sending and signal-receipt should sufficiently serialize accesses to the field. Hence, this isn't any riskier than the existing usages of pmsignal.c. We might in future extend this idea to improve other postmaster-to-children signal scenarios, although none of them currently seem to be as badly overloaded as SIGQUIT. Discussion: https://postgr.es/m/559291.1608587013@sss.pgh.pa.us --- src/backend/tcop/postgres.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) (limited to 'src/backend/tcop/postgres.c') diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 3679799e50a..d35c5020ea6 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -67,6 +67,7 @@ #include "rewrite/rewriteHandler.h" #include "storage/bufmgr.h" #include "storage/ipc.h" +#include "storage/pmsignal.h" #include "storage/proc.h" #include "storage/procsignal.h" #include "storage/sinval.h" @@ -2752,8 +2753,8 @@ drop_unnamed_stmt(void) /* * quickdie() occurs when signaled SIGQUIT by the postmaster. * - * Some backend has bought the farm, - * so we need to stop what we're doing and exit. + * Either some backend has bought the farm, or we've been told to shut down + * "immediately"; so we need to stop what we're doing and exit. */ void quickdie(SIGNAL_ARGS) @@ -2788,18 +2789,36 @@ quickdie(SIGNAL_ARGS) * wrong, so there's not much to lose. Assuming the postmaster is still * running, it will SIGKILL us soon if we get stuck for some reason. * - * Ideally this should be ereport(FATAL), but then we'd not get control - * back... + * Ideally these should be ereport(FATAL), but then we'd not get control + * back to force the correct type of process exit. */ - ereport(WARNING, - (errcode(ERRCODE_CRASH_SHUTDOWN), - errmsg("terminating connection because of crash of another server process"), - errdetail("The postmaster has commanded this server process to roll back" - " the current transaction and exit, because another" - " server process exited abnormally and possibly corrupted" - " shared memory."), - errhint("In a moment you should be able to reconnect to the" - " database and repeat your command."))); + switch (GetQuitSignalReason()) + { + case PMQUIT_NOT_SENT: + /* Hmm, SIGQUIT arrived out of the blue */ + ereport(WARNING, + (errcode(ERRCODE_ADMIN_SHUTDOWN), + errmsg("terminating connection because of unexpected SIGQUIT signal"))); + break; + case PMQUIT_FOR_CRASH: + /* A crash-and-restart cycle is in progress */ + ereport(WARNING, + (errcode(ERRCODE_CRASH_SHUTDOWN), + errmsg("terminating connection because of crash of another server process"), + errdetail("The postmaster has commanded this server process to roll back" + " the current transaction and exit, because another" + " server process exited abnormally and possibly corrupted" + " shared memory."), + errhint("In a moment you should be able to reconnect to the" + " database and repeat your command."))); + break; + case PMQUIT_FOR_STOP: + /* Immediate-mode stop */ + ereport(WARNING, + (errcode(ERRCODE_ADMIN_SHUTDOWN), + errmsg("terminating connection due to immediate shutdown command"))); + break; + } /* * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here -- cgit v1.2.3