]> granicus.if.org Git - postgresql/commitdiff
Unify SIGHUP handling between normal and walsender backends.
authorAndres Freund <andres@anarazel.de>
Tue, 6 Jun 2017 01:53:42 +0000 (18:53 -0700)
committerAndres Freund <andres@anarazel.de>
Tue, 6 Jun 2017 02:18:16 +0000 (19:18 -0700)
Because walsender and normal backends share the same main loop it's
problematic to have two different flag variables, set in signal
handlers, indicating a pending configuration reload.  Only certain
walsender commands reach code paths checking for the
variable (START_[LOGICAL_]REPLICATION, CREATE_REPLICATION_SLOT
... LOGICAL, notably not base backups).

This is a bug present since the introduction of walsender, but has
gotten worse in releases since then which allow walsender to do more.

A later patch, not slated for v10, will similarly unify SIGHUP
handling in other types of processes as well.

Author: Petr Jelinek, Andres Freund
Reviewed-By: Michael Paquier
Discussion: https://postgr.es/m/20170423235941.qosiuoyqprq4nu7v@alap3.anarazel.de
Backpatch: 9.2-, bug is present since 9.0

src/backend/replication/walsender.c
src/backend/tcop/postgres.c
src/backend/utils/init/globals.c
src/include/miscadmin.h

index 9b455eef58579269a45ade70e721cfd6d89ba2f6..14ad50b737e7bf6256b4c084a93eed7bc909c5a9 100644 (file)
@@ -166,7 +166,6 @@ static volatile sig_atomic_t walsender_ready_to_stop = false;
 static volatile sig_atomic_t replication_active = false;
 
 /* Signal handlers */
-static void WalSndSigHupHandler(SIGNAL_ARGS);
 static void WalSndXLogSendHandler(SIGNAL_ARGS);
 static void WalSndLastCycleHandler(SIGNAL_ARGS);
 
@@ -979,9 +978,9 @@ WalSndLoop(void)
                        exit(1);
 
                /* Process any requests or signals received recently */
-               if (got_SIGHUP)
+               if (ConfigReloadPending)
                {
-                       got_SIGHUP = false;
+                       ConfigReloadPending = false;
                        ProcessConfigFile(PGC_SIGHUP);
                        SyncRepInitConfig();
                }
@@ -1712,19 +1711,6 @@ WalSndRqstFileReload(void)
        }
 }
 
-/* SIGHUP: set flag to re-read config file at next convenient time */
-static void
-WalSndSigHupHandler(SIGNAL_ARGS)
-{
-       int                     save_errno = errno;
-
-       got_SIGHUP = true;
-       if (MyWalSnd)
-               SetLatch(&MyWalSnd->latch);
-
-       errno = save_errno;
-}
-
 /* SIGUSR1: set flag to send WAL records */
 static void
 WalSndXLogSendHandler(SIGNAL_ARGS)
@@ -1763,7 +1749,7 @@ void
 WalSndSignals(void)
 {
        /* Set up signal handlers */
-       pqsignal(SIGHUP, WalSndSigHupHandler);          /* set flag to read config
+       pqsignal(SIGHUP, PostgresSigHupHandler);        /* set flag to read config
                                                                                                 * file */
        pqsignal(SIGINT, SIG_IGN);      /* not used */
        pqsignal(SIGTERM, die);         /* request shutdown */
index 4c140ee3154fc452e792f87e9556af5a64de1af2..538f9f3d32d966df644d26a8983815d85ef15e40 100644 (file)
@@ -130,13 +130,6 @@ char          *stack_base_ptr = NULL;
 char      *register_stack_base_ptr = NULL;
 #endif
 
-/*
- * Flag to mark SIGHUP. Whenever the main loop comes around it
- * will reread the configuration file. (Better than doing the
- * reading in the signal handler, ey?)
- */
-static volatile sig_atomic_t got_SIGHUP = false;
-
 /*
  * Flag to keep track of whether we have started a transaction.
  * For extended query protocol this has to be remembered across messages.
@@ -205,7 +198,6 @@ static bool IsTransactionExitStmt(Node *parsetree);
 static bool IsTransactionExitStmtList(List *parseTrees);
 static bool IsTransactionStmtList(List *parseTrees);
 static void drop_unnamed_stmt(void);
-static void SigHupHandler(SIGNAL_ARGS);
 static void log_disconnections(int code, Datum arg);
 
 
@@ -2685,13 +2677,19 @@ FloatExceptionHandler(SIGNAL_ARGS)
                                           "invalid operation, such as division by zero.")));
 }
 
-/* SIGHUP: set flag to re-read config file at next convenient time */
-static void
-SigHupHandler(SIGNAL_ARGS)
+/*
+ * SIGHUP: set flag to re-read config file at next convenient time.
+ *
+ * Sets the ConfigReloadPending flag, which should be checked at convenient
+ * places inside main loops. (Better than doing the reading in the signal
+ * handler, ey?)
+ */
+void
+PostgresSigHupHandler(SIGNAL_ARGS)
 {
        int                     save_errno = errno;
 
-       got_SIGHUP = true;
+       ConfigReloadPending = true;
        if (MyProc)
                SetLatch(&MyProc->procLatch);
 
@@ -3683,8 +3681,8 @@ PostgresMain(int argc, char *argv[],
                WalSndSignals();
        else
        {
-               pqsignal(SIGHUP, SigHupHandler);                /* set flag to read config
-                                                                                                * file */
+               pqsignal(SIGHUP, PostgresSigHupHandler);                /* set flag to read config
+                                                                                                                * file */
                pqsignal(SIGINT, StatementCancelHandler);               /* cancel current query */
                pqsignal(SIGTERM, die); /* cancel current query and exit */
 
@@ -4062,9 +4060,9 @@ PostgresMain(int argc, char *argv[],
                 * (5) check for any other interesting events that happened while we
                 * slept.
                 */
-               if (got_SIGHUP)
+               if (ConfigReloadPending)
                {
-                       got_SIGHUP = false;
+                       ConfigReloadPending = false;
                        ProcessConfigFile(PGC_SIGHUP);
                }
 
index 10463c6703dc56a0aec719cced1b1640aedc8f39..80e30833549751ba10ce172080ce0befeb44a5d9 100644 (file)
@@ -30,6 +30,7 @@ volatile bool QueryCancelPending = false;
 volatile bool ProcDiePending = false;
 volatile bool ClientConnectionLost = false;
 volatile bool ImmediateInterruptOK = false;
+volatile sig_atomic_t ConfigReloadPending = false;
 volatile uint32 InterruptHoldoffCount = 0;
 volatile uint32 QueryCancelHoldoffCount = 0;
 volatile uint32 CritSectionCount = 0;
index f88a49183b311c4cbc41ef4cf5aafe73f0491e38..d0ec3914e08d07b3f41c6a4d6c8995653e089d02 100644 (file)
@@ -23,6 +23,8 @@
 #ifndef MISCADMIN_H
 #define MISCADMIN_H
 
+#include <signal.h>
+
 #include "pgtime.h"                            /* for pg_time_t */
 
 
@@ -78,6 +80,7 @@
 extern PGDLLIMPORT volatile bool InterruptPending;
 extern volatile bool QueryCancelPending;
 extern volatile bool ProcDiePending;
+extern PGDLLIMPORT volatile sig_atomic_t ConfigReloadPending;
 
 extern volatile bool ClientConnectionLost;
 
@@ -276,6 +279,8 @@ extern void restore_stack_base(pg_stack_base_t base);
 extern void check_stack_depth(void);
 extern bool stack_is_too_deep(void);
 
+extern void PostgresSigHupHandler(SIGNAL_ARGS);
+
 /* in tcop/utility.c */
 extern void PreventCommandIfReadOnly(const char *cmdname);
 extern void PreventCommandDuringRecovery(const char *cmdname);