diff options
Diffstat (limited to 'src/backend/postmaster')
| -rw-r--r-- | src/backend/postmaster/Makefile | 1 | ||||
| -rw-r--r-- | src/backend/postmaster/autovacuum.c | 29 | ||||
| -rw-r--r-- | src/backend/postmaster/bgworker.c | 25 | ||||
| -rw-r--r-- | src/backend/postmaster/bgwriter.c | 93 | ||||
| -rw-r--r-- | src/backend/postmaster/checkpointer.c | 60 | ||||
| -rw-r--r-- | src/backend/postmaster/interrupt.c | 108 | ||||
| -rw-r--r-- | src/backend/postmaster/pgarch.c | 29 | ||||
| -rw-r--r-- | src/backend/postmaster/pgstat.c | 28 | ||||
| -rw-r--r-- | src/backend/postmaster/startup.c | 34 | ||||
| -rw-r--r-- | src/backend/postmaster/walwriter.c | 84 |
10 files changed, 149 insertions, 342 deletions
diff --git a/src/backend/postmaster/Makefile b/src/backend/postmaster/Makefile index 03e3d3650ae..bfdf6a833db 100644 --- a/src/backend/postmaster/Makefile +++ b/src/backend/postmaster/Makefile @@ -18,6 +18,7 @@ OBJS = \ bgwriter.o \ checkpointer.o \ fork_process.o \ + interrupt.o \ pgarch.o \ pgstat.o \ postmaster.o \ diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index b1c2b0a01c2..1792008ebe5 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -84,6 +84,7 @@ #include "pgstat.h" #include "postmaster/autovacuum.h" #include "postmaster/fork_process.h" +#include "postmaster/interrupt.h" #include "postmaster/postmaster.h" #include "storage/bufmgr.h" #include "storage/ipc.h" @@ -139,7 +140,6 @@ static bool am_autovacuum_worker = false; /* Flags set by signal handlers */ static volatile sig_atomic_t got_SIGUSR2 = false; -static volatile sig_atomic_t got_SIGTERM = false; /* Comparison points for determining whether freeze_max_age is exceeded */ static TransactionId recentXid; @@ -344,7 +344,6 @@ static void autovac_report_activity(autovac_table *tab); static void autovac_report_workitem(AutoVacuumWorkItem *workitem, const char *nspname, const char *relname); static void avl_sigusr2_handler(SIGNAL_ARGS); -static void avl_sigterm_handler(SIGNAL_ARGS); static void autovac_refresh_stats(void); @@ -450,9 +449,9 @@ AutoVacLauncherMain(int argc, char *argv[]) * backend, so we use the same signal handling. See equivalent code in * tcop/postgres.c. */ - pqsignal(SIGHUP, PostgresSigHupHandler); + pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, StatementCancelHandler); - pqsignal(SIGTERM, avl_sigterm_handler); + pqsignal(SIGTERM, SignalHandlerForShutdownRequest); pqsignal(SIGQUIT, quickdie); InitializeTimeouts(); /* establishes SIGALRM handler */ @@ -553,7 +552,7 @@ AutoVacLauncherMain(int argc, char *argv[]) RESUME_INTERRUPTS(); /* if in shutdown mode, no need for anything further; just go away */ - if (got_SIGTERM) + if (ShutdownRequestPending) AutoVacLauncherShutdown(); /* @@ -605,7 +604,7 @@ AutoVacLauncherMain(int argc, char *argv[]) */ if (!AutoVacuumingActive()) { - if (!got_SIGTERM) + if (!ShutdownRequestPending) do_start_worker(); proc_exit(0); /* done */ } @@ -622,7 +621,7 @@ AutoVacLauncherMain(int argc, char *argv[]) rebuild_database_list(InvalidOid); /* loop until shutdown request */ - while (!got_SIGTERM) + while (!ShutdownRequestPending) { struct timeval nap; TimestampTz current_time = 0; @@ -800,7 +799,7 @@ static void HandleAutoVacLauncherInterrupts(void) { /* the normal shutdown case */ - if (got_SIGTERM) + if (ShutdownRequestPending) AutoVacLauncherShutdown(); if (ConfigReloadPending) @@ -1415,18 +1414,6 @@ avl_sigusr2_handler(SIGNAL_ARGS) errno = save_errno; } -/* SIGTERM: time to die */ -static void -avl_sigterm_handler(SIGNAL_ARGS) -{ - int save_errno = errno; - - got_SIGTERM = true; - SetLatch(MyLatch); - - errno = save_errno; -} - /******************************************************************** * AUTOVACUUM WORKER CODE @@ -1525,7 +1512,7 @@ AutoVacWorkerMain(int argc, char *argv[]) * backend, so we use the same signal handling. See equivalent code in * tcop/postgres.c. */ - pqsignal(SIGHUP, PostgresSigHupHandler); + pqsignal(SIGHUP, SignalHandlerForConfigReload); /* * SIGINT is used to signal canceling the current table's vacuum; SIGTERM diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 5f8a007e73c..a4c347d5246 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -12,14 +12,13 @@ #include "postgres.h" -#include <unistd.h> - #include "access/parallel.h" #include "libpq/pqsignal.h" #include "miscadmin.h" #include "pgstat.h" #include "port/atomics.h" #include "postmaster/bgworker_internals.h" +#include "postmaster/interrupt.h" #include "postmaster/postmaster.h" #include "replication/logicallauncher.h" #include "replication/logicalworker.h" @@ -641,26 +640,6 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel) return true; } -static void -bgworker_quickdie(SIGNAL_ARGS) -{ - /* - * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here - * because shared memory may be corrupted, so we don't want to try to - * clean up our transaction. Just nail the windows shut and get out of - * town. The callbacks wouldn't be safe to run from a signal handler, - * anyway. - * - * Note we do _exit(2) not _exit(0). This is to force the postmaster into - * a system reset cycle if someone sends a manual SIGQUIT to a random - * backend. This is necessary precisely because we don't clean up our - * shared memory state. (The "dead man switch" mechanism in pmsignal.c - * should ensure the postmaster sees this as a crash, too, but no harm in - * being doubly sure.) - */ - _exit(2); -} - /* * Standard SIGTERM handler for background workers */ @@ -754,7 +733,7 @@ StartBackgroundWorker(void) pqsignal(SIGTERM, bgworker_die); pqsignal(SIGHUP, SIG_IGN); - pqsignal(SIGQUIT, bgworker_quickdie); + pqsignal(SIGQUIT, SignalHandlerForCrashExit); InitializeTimeouts(); /* establishes SIGALRM handler */ pqsignal(SIGPIPE, SIG_IGN); diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c index bca46de6d56..9cc343b74f5 100644 --- a/src/backend/postmaster/bgwriter.c +++ b/src/backend/postmaster/bgwriter.c @@ -34,16 +34,13 @@ */ #include "postgres.h" -#include <signal.h> -#include <sys/time.h> -#include <unistd.h> - #include "access/xlog.h" #include "access/xlog_internal.h" #include "libpq/pqsignal.h" #include "miscadmin.h" #include "pgstat.h" #include "postmaster/bgwriter.h" +#include "postmaster/interrupt.h" #include "storage/buf_internals.h" #include "storage/bufmgr.h" #include "storage/condition_variable.h" @@ -86,18 +83,6 @@ int BgWriterDelay = 200; static TimestampTz last_snapshot_ts; static XLogRecPtr last_snapshot_lsn = InvalidXLogRecPtr; -/* - * Flags set by interrupt handlers for later service in the main loop. - */ -static volatile sig_atomic_t shutdown_requested = false; - -static void HandleBackgroundWriterInterrupts(void); - -/* Signal handlers */ - -static void bg_quickdie(SIGNAL_ARGS); -static void ReqShutdownHandler(SIGNAL_ARGS); - /* * Main entry point for bgwriter process @@ -116,10 +101,10 @@ BackgroundWriterMain(void) /* * Properly accept or ignore signals that might be sent to us. */ - pqsignal(SIGHUP, PostgresSigHupHandler); /* set flag to read config file */ + pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, SIG_IGN); - pqsignal(SIGTERM, ReqShutdownHandler); /* shutdown */ - pqsignal(SIGQUIT, bg_quickdie); /* hard crash time */ + pqsignal(SIGTERM, SignalHandlerForShutdownRequest); + pqsignal(SIGQUIT, SignalHandlerForCrashExit); pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, procsignal_sigusr1_handler); @@ -241,7 +226,7 @@ BackgroundWriterMain(void) /* Clear any already-pending wakeups */ ResetLatch(MyLatch); - HandleBackgroundWriterInterrupts(); + HandleMainLoopInterrupts(); /* * Do one cycle of dirty-buffer writing. @@ -354,71 +339,3 @@ BackgroundWriterMain(void) prev_hibernate = can_hibernate; } } - -/* - * Process any new interrupts. - */ -static void -HandleBackgroundWriterInterrupts(void) -{ - if (ConfigReloadPending) - { - ConfigReloadPending = false; - ProcessConfigFile(PGC_SIGHUP); - } - - if (shutdown_requested) - { - /* - * From here on, elog(ERROR) should end with exit(1), not send - * control back to the sigsetjmp block above - */ - ExitOnAnyError = true; - /* Normal exit from the bgwriter is here */ - proc_exit(0); /* done */ - } -} - - -/* -------------------------------- - * signal handler routines - * -------------------------------- - */ - -/* - * bg_quickdie() occurs when signalled SIGQUIT by the postmaster. - * - * Some backend has bought the farm, - * so we need to stop what we're doing and exit. - */ -static void -bg_quickdie(SIGNAL_ARGS) -{ - /* - * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here - * because shared memory may be corrupted, so we don't want to try to - * clean up our transaction. Just nail the windows shut and get out of - * town. The callbacks wouldn't be safe to run from a signal handler, - * anyway. - * - * Note we do _exit(2) not _exit(0). This is to force the postmaster into - * a system reset cycle if someone sends a manual SIGQUIT to a random - * backend. This is necessary precisely because we don't clean up our - * shared memory state. (The "dead man switch" mechanism in pmsignal.c - * should ensure the postmaster sees this as a crash, too, but no harm in - * being doubly sure.) - */ - _exit(2); -} - -/* SIGTERM: set flag to shutdown and exit */ -static void -ReqShutdownHandler(SIGNAL_ARGS) -{ - int save_errno = errno; - - shutdown_requested = true; - SetLatch(MyLatch); - - errno = save_errno; -} diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index 9cf91b0d35c..3f35b324c33 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -36,10 +36,7 @@ */ #include "postgres.h" -#include <signal.h> #include <sys/time.h> -#include <time.h> -#include <unistd.h> #include "access/xlog.h" #include "access/xlog_internal.h" @@ -47,6 +44,7 @@ #include "miscadmin.h" #include "pgstat.h" #include "postmaster/bgwriter.h" +#include "postmaster/interrupt.h" #include "replication/syncrep.h" #include "storage/bufmgr.h" #include "storage/condition_variable.h" @@ -149,11 +147,6 @@ int CheckPointWarning = 30; double CheckPointCompletionTarget = 0.5; /* - * Flags set by interrupt handlers for later service in the main loop. - */ -static volatile sig_atomic_t shutdown_requested = false; - -/* * Private state */ static bool ckpt_active = false; @@ -176,10 +169,7 @@ static bool CompactCheckpointerRequestQueue(void); static void UpdateSharedMemoryConfig(void); /* Signal handlers */ - -static void chkpt_quickdie(SIGNAL_ARGS); static void ReqCheckpointHandler(SIGNAL_ARGS); -static void ReqShutdownHandler(SIGNAL_ARGS); /* @@ -204,14 +194,14 @@ CheckpointerMain(void) * want to wait for the backends to exit, whereupon the postmaster will * tell us it's okay to shut down (via SIGUSR2). */ - pqsignal(SIGHUP, PostgresSigHupHandler); /* set flag to read config file */ + pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, ReqCheckpointHandler); /* request checkpoint */ pqsignal(SIGTERM, SIG_IGN); /* ignore SIGTERM */ - pqsignal(SIGQUIT, chkpt_quickdie); /* hard crash time */ + pqsignal(SIGQUIT, SignalHandlerForCrashExit); pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, procsignal_sigusr1_handler); - pqsignal(SIGUSR2, ReqShutdownHandler); /* request shutdown */ + pqsignal(SIGUSR2, SignalHandlerForShutdownRequest); /* * Reset some signals that are accepted by postmaster but not here @@ -551,7 +541,7 @@ HandleCheckpointerInterrupts(void) */ UpdateSharedMemoryConfig(); } - if (shutdown_requested) + if (ShutdownRequestPending) { /* * From here on, elog(ERROR) should end with exit(1), not send @@ -679,7 +669,7 @@ CheckpointWriteDelay(int flags, double progress) * in which case we just try to catch up as quickly as possible. */ if (!(flags & CHECKPOINT_IMMEDIATE) && - !shutdown_requested && + !ShutdownRequestPending && !ImmediateCheckpointRequested() && IsCheckpointOnSchedule(progress)) { @@ -807,32 +797,6 @@ IsCheckpointOnSchedule(double progress) * -------------------------------- */ -/* - * chkpt_quickdie() occurs when signalled SIGQUIT by the postmaster. - * - * Some backend has bought the farm, - * so we need to stop what we're doing and exit. - */ -static void -chkpt_quickdie(SIGNAL_ARGS) -{ - /* - * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here - * because shared memory may be corrupted, so we don't want to try to - * clean up our transaction. Just nail the windows shut and get out of - * town. The callbacks wouldn't be safe to run from a signal handler, - * anyway. - * - * Note we do _exit(2) not _exit(0). This is to force the postmaster into - * a system reset cycle if someone sends a manual SIGQUIT to a random - * backend. This is necessary precisely because we don't clean up our - * shared memory state. (The "dead man switch" mechanism in pmsignal.c - * should ensure the postmaster sees this as a crash, too, but no harm in - * being doubly sure.) - */ - _exit(2); -} - /* SIGINT: set flag to run a normal checkpoint right away */ static void ReqCheckpointHandler(SIGNAL_ARGS) @@ -848,18 +812,6 @@ ReqCheckpointHandler(SIGNAL_ARGS) errno = save_errno; } -/* SIGUSR2: set flag to run a shutdown checkpoint and exit */ -static void -ReqShutdownHandler(SIGNAL_ARGS) -{ - int save_errno = errno; - - shutdown_requested = true; - SetLatch(MyLatch); - - errno = save_errno; -} - /* -------------------------------- * communication with backends diff --git a/src/backend/postmaster/interrupt.c b/src/backend/postmaster/interrupt.c new file mode 100644 index 00000000000..6900cd02f6f --- /dev/null +++ b/src/backend/postmaster/interrupt.c @@ -0,0 +1,108 @@ +/*------------------------------------------------------------------------- + * + * interrupt.c + * Interrupt handling routines. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/postmaster/interrupt.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include <unistd.h> + +#include "miscadmin.h" +#include "postmaster/interrupt.h" +#include "storage/ipc.h" +#include "storage/latch.h" +#include "utils/guc.h" + +volatile sig_atomic_t ConfigReloadPending = false; +volatile sig_atomic_t ShutdownRequestPending = false; + +/* + * Simple interrupt handler for main loops of background processes. + */ +void +HandleMainLoopInterrupts(void) +{ + if (ConfigReloadPending) + { + ConfigReloadPending = false; + ProcessConfigFile(PGC_SIGHUP); + } + + if (ShutdownRequestPending) + proc_exit(0); +} + +/* + * Simple signal handler for triggering a configuration reload. + * + * Normally, this handler would be used for SIGHUP. The idea is that code + * which uses it would arrange to check the ConfigReloadPending flag at + * convenient places inside main loops, or else call HandleMainLoopInterrupts. + */ +void +SignalHandlerForConfigReload(SIGNAL_ARGS) +{ + int save_errno = errno; + + ConfigReloadPending = true; + SetLatch(MyLatch); + + errno = save_errno; +} + +/* + * Simple signal handler for exiting quickly as if due to a crash. + * + * Normally, this would be used for handling SIGQUIT. + */ +void +SignalHandlerForCrashExit(SIGNAL_ARGS) +{ + /* + * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here + * because shared memory may be corrupted, so we don't want to try to + * clean up our transaction. Just nail the windows shut and get out of + * town. The callbacks wouldn't be safe to run from a signal handler, + * anyway. + * + * Note we do _exit(2) not _exit(0). This is to force the postmaster into + * a system reset cycle if someone sends a manual SIGQUIT to a random + * backend. This is necessary precisely because we don't clean up our + * shared memory state. (The "dead man switch" mechanism in pmsignal.c + * should ensure the postmaster sees this as a crash, too, but no harm in + * being doubly sure.) + */ + _exit(2); +} + +/* + * Simple signal handler for triggering a long-running background process to + * shut down and exit. + * + * Typically, this handler would be used for SIGTERM, but some procesess use + * other signals. In particular, the checkpointer exits on SIGUSR2, the + * stats collector on SIGQUIT, and the WAL writer exits on either SIGINT + * or SIGTERM. + * + * ShutdownRequestPending should be checked at a convenient place within the + * main loop, or else the main loop should call HandleMainLoopInterrupts. + */ +void +SignalHandlerForShutdownRequest(SIGNAL_ARGS) +{ + int save_errno = errno; + + ShutdownRequestPending = true; + SetLatch(MyLatch); + + errno = save_errno; +} diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c index 09a9c66b4b2..7824180ac7f 100644 --- a/src/backend/postmaster/pgarch.c +++ b/src/backend/postmaster/pgarch.c @@ -39,6 +39,7 @@ #include "miscadmin.h" #include "pgstat.h" #include "postmaster/fork_process.h" +#include "postmaster/interrupt.h" #include "postmaster/pgarch.h" #include "postmaster/postmaster.h" #include "storage/dsm.h" @@ -83,7 +84,6 @@ static time_t last_sigterm_time = 0; /* * Flags set by interrupt handlers for later service in the main loop. */ -static volatile sig_atomic_t got_SIGTERM = false; static volatile sig_atomic_t wakened = false; static volatile sig_atomic_t ready_to_stop = false; @@ -97,7 +97,6 @@ static pid_t pgarch_forkexec(void); NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]) pg_attribute_noreturn(); static void pgarch_exit(SIGNAL_ARGS); -static void ArchSigTermHandler(SIGNAL_ARGS); static void pgarch_waken(SIGNAL_ARGS); static void pgarch_waken_stop(SIGNAL_ARGS); static void pgarch_MainLoop(void); @@ -227,9 +226,9 @@ PgArchiverMain(int argc, char *argv[]) * Ignore all signals usually bound to some action in the postmaster, * except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT. */ - pqsignal(SIGHUP, PostgresSigHupHandler); + pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, SIG_IGN); - pqsignal(SIGTERM, ArchSigTermHandler); + pqsignal(SIGTERM, SignalHandlerForShutdownRequest); pqsignal(SIGQUIT, pgarch_exit); pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); @@ -257,24 +256,6 @@ pgarch_exit(SIGNAL_ARGS) exit(1); } -/* SIGTERM signal handler for archiver process */ -static void -ArchSigTermHandler(SIGNAL_ARGS) -{ - int save_errno = errno; - - /* - * The postmaster never sends us SIGTERM, so we assume that this means - * that init is trying to shut down the whole system. If we hang around - * too long we'll get SIGKILL'd. Set flag to prevent starting any more - * archive commands. - */ - got_SIGTERM = true; - SetLatch(MyLatch); - - errno = save_errno; -} - /* SIGUSR1 signal handler for archiver process */ static void pgarch_waken(SIGNAL_ARGS) @@ -346,7 +327,7 @@ pgarch_MainLoop(void) * idea. If more than 60 seconds pass since SIGTERM, exit anyway, so * that the postmaster can start a new archiver if needed. */ - if (got_SIGTERM) + if (ShutdownRequestPending) { time_t curtime = time(NULL); @@ -434,7 +415,7 @@ pgarch_ArchiverCopyLoop(void) * command, and the second is to avoid conflicts with another * archiver spawned by a newer postmaster. */ - if (got_SIGTERM || !PostmasterIsAlive()) + if (ShutdownRequestPending || !PostmasterIsAlive()) return; /* diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 96a9e09cedc..e9315122033 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -49,6 +49,7 @@ #include "pgstat.h" #include "postmaster/autovacuum.h" #include "postmaster/fork_process.h" +#include "postmaster/interrupt.h" #include "postmaster/postmaster.h" #include "replication/walsender.h" #include "storage/backendid.h" @@ -262,9 +263,6 @@ static PgStat_GlobalStats globalStats; */ static List *pending_write_requests = NIL; -/* Signal handler flags */ -static volatile bool need_exit = false; - /* * Total time charged to functions so far in the current backend. * We use this to help separate "self" and "other" time charges. @@ -282,7 +280,6 @@ static pid_t pgstat_forkexec(void); #endif NON_EXEC_STATIC void PgstatCollectorMain(int argc, char *argv[]) pg_attribute_noreturn(); -static void pgstat_exit(SIGNAL_ARGS); static void pgstat_beshutdown_hook(int code, Datum arg); static PgStat_StatDBEntry *pgstat_get_db_entry(Oid databaseid, bool create); @@ -4432,10 +4429,10 @@ PgstatCollectorMain(int argc, char *argv[]) * except SIGHUP and SIGQUIT. Note we don't need a SIGUSR1 handler to * support latch operations, because we only use a local latch. */ - pqsignal(SIGHUP, PostgresSigHupHandler); + pqsignal(SIGHUP, SignalHandlerForConfigReload); pqsignal(SIGINT, SIG_IGN); pqsignal(SIGTERM, SIG_IGN); - pqsignal(SIGQUIT, pgstat_exit); + pqsignal(SIGQUIT, SignalHandlerForShutdownRequest); pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, SIG_IGN); @@ -4477,14 +4474,14 @@ PgstatCollectorMain(int argc, char *argv[]) /* * Quit if we get SIGQUIT from the postmaster. */ - if (need_exit) + if (ShutdownRequestPending) break; /* * Inner loop iterates as long as we keep getting messages, or until - * need_exit becomes set. + * ShutdownRequestPending becomes set. */ - while (!need_exit) + while (!ShutdownRequestPending) { /* * Reload configuration if we got SIGHUP from the postmaster. @@ -4676,19 +4673,6 @@ PgstatCollectorMain(int argc, char *argv[]) exit(0); } - -/* SIGQUIT signal handler for collector process */ -static void -pgstat_exit(SIGNAL_ARGS) -{ - int save_errno = errno; - - need_exit = true; - SetLatch(MyLatch); - - errno = save_errno; -} - /* * Subroutine to clear stats in a database entry * diff --git a/src/backend/postmaster/startup.c b/src/backend/postmaster/startup.c index f43e57dadb9..4f59c71f733 100644 --- a/src/backend/postmaster/startup.c +++ b/src/backend/postmaster/startup.c @@ -19,13 +19,11 @@ */ #include "postgres.h" -#include <signal.h> -#include <unistd.h> - #include "access/xlog.h" #include "libpq/pqsignal.h" #include "miscadmin.h" #include "pgstat.h" +#include "postmaster/interrupt.h" #include "postmaster/startup.h" #include "storage/ipc.h" #include "storage/latch.h" @@ -50,7 +48,6 @@ static volatile sig_atomic_t promote_triggered = false; static volatile sig_atomic_t in_restore_command = false; /* Signal handlers */ -static void startupproc_quickdie(SIGNAL_ARGS); static void StartupProcTriggerHandler(SIGNAL_ARGS); static void StartupProcSigHupHandler(SIGNAL_ARGS); @@ -60,33 +57,6 @@ static void StartupProcSigHupHandler(SIGNAL_ARGS); * -------------------------------- */ -/* - * startupproc_quickdie() occurs when signalled SIGQUIT by the postmaster. - * - * Some backend has bought the farm, - * so we need to stop what we're doing and exit. - */ -static void -startupproc_quickdie(SIGNAL_ARGS) -{ - /* - * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here - * because shared memory may be corrupted, so we don't want to try to - * clean up our transaction. Just nail the windows shut and get out of - * town. The callbacks wouldn't be safe to run from a signal handler, - * anyway. - * - * Note we do _exit(2) not _exit(0). This is to force the postmaster into - * a system reset cycle if someone sends a manual SIGQUIT to a random - * backend. This is necessary precisely because we don't clean up our - * shared memory state. (The "dead man switch" mechanism in pmsignal.c - * should ensure the postmaster sees this as a crash, too, but no harm in - * being doubly sure.) - */ - _exit(2); -} - - /* SIGUSR2: set flag to finish recovery */ static void StartupProcTriggerHandler(SIGNAL_ARGS) @@ -167,7 +137,7 @@ StartupProcessMain(void) pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */ pqsignal(SIGINT, SIG_IGN); /* ignore query cancel */ pqsignal(SIGTERM, StartupProcShutdownHandler); /* request shutdown */ - pqsignal(SIGQUIT, startupproc_quickdie); /* hard crash time */ + pqsignal(SIGQUIT, SignalHandlerForCrashExit); InitializeTimeouts(); /* establishes SIGALRM handler */ pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, procsignal_sigusr1_handler); diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c index 599478530f9..38e9eb1304e 100644 --- a/src/backend/postmaster/walwriter.c +++ b/src/backend/postmaster/walwriter.c @@ -48,6 +48,7 @@ #include "libpq/pqsignal.h" #include "miscadmin.h" #include "pgstat.h" +#include "postmaster/interrupt.h" #include "postmaster/walwriter.h" #include "storage/bufmgr.h" #include "storage/condition_variable.h" @@ -78,17 +79,6 @@ int WalWriterFlushAfter = 128; #define HIBERNATE_FACTOR 25 /* - * Flags set by interrupt handlers for later service in the main loop. - */ -static volatile sig_atomic_t shutdown_requested = false; - -static void HandleWalWriterInterrupts(void); - -/* Signal handlers */ -static void wal_quickdie(SIGNAL_ARGS); -static void WalShutdownHandler(SIGNAL_ARGS); - -/* * Main entry point for walwriter process * * This is invoked from AuxiliaryProcessMain, which has already created the @@ -108,10 +98,10 @@ WalWriterMain(void) * We have no particular use for SIGINT at the moment, but seems * reasonable to treat like SIGTERM. */ - pqsignal(SIGHUP, PostgresSigHupHandler); /* set flag to read config file */ - pqsignal(SIGINT, WalShutdownHandler); /* request shutdown */ - pqsignal(SIGTERM, WalShutdownHandler); /* request shutdown */ - pqsignal(SIGQUIT, wal_quickdie); /* hard crash time */ + pqsignal(SIGHUP, SignalHandlerForConfigReload); + pqsignal(SIGINT, SignalHandlerForShutdownRequest); + pqsignal(SIGTERM, SignalHandlerForShutdownRequest); + pqsignal(SIGQUIT, SignalHandlerForCrashExit); pqsignal(SIGALRM, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, procsignal_sigusr1_handler); @@ -242,7 +232,7 @@ WalWriterMain(void) /* Clear any already-pending wakeups */ ResetLatch(MyLatch); - HandleWalWriterInterrupts(); + HandleMainLoopInterrupts(); /* * Do what we're here for; then, if XLogBackgroundFlush() found useful @@ -269,65 +259,3 @@ WalWriterMain(void) WAIT_EVENT_WAL_WRITER_MAIN); } } - -/* - * Process any new interrupts. - */ -static void -HandleWalWriterInterrupts(void) -{ - if (ConfigReloadPending) - { - ConfigReloadPending = false; - ProcessConfigFile(PGC_SIGHUP); - } - if (shutdown_requested) - { - /* Normal exit from the walwriter is here */ - proc_exit(0); /* done */ - } -} - - -/* -------------------------------- - * signal handler routines - * -------------------------------- - */ - -/* - * wal_quickdie() occurs when signalled SIGQUIT by the postmaster. - * - * Some backend has bought the farm, - * so we need to stop what we're doing and exit. - */ -static void -wal_quickdie(SIGNAL_ARGS) -{ - /* - * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here - * because shared memory may be corrupted, so we don't want to try to - * clean up our transaction. Just nail the windows shut and get out of - * town. The callbacks wouldn't be safe to run from a signal handler, - * anyway. - * - * Note we do _exit(2) not _exit(0). This is to force the postmaster into - * a system reset cycle if someone sends a manual SIGQUIT to a random - * backend. This is necessary precisely because we don't clean up our - * shared memory state. (The "dead man switch" mechanism in pmsignal.c - * should ensure the postmaster sees this as a crash, too, but no harm in - * being doubly sure.) - */ - _exit(2); -} - -/* SIGTERM: set flag to exit normally */ -static void -WalShutdownHandler(SIGNAL_ARGS) -{ - int save_errno = errno; - - shutdown_requested = true; - SetLatch(MyLatch); - - errno = save_errno; -} |
