LCOV - code coverage report
Current view: top level - src/backend/postmaster - startup.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 70 75 93.3 %
Date: 2020-06-03 11:07:14 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * startup.c
       4             :  *
       5             :  * The Startup process initialises the server and performs any recovery
       6             :  * actions that have been specified. Notice that there is no "main loop"
       7             :  * since the Startup process ends as soon as initialisation is complete.
       8             :  * (in standby mode, one can think of the replay loop as a main loop,
       9             :  * though.)
      10             :  *
      11             :  *
      12             :  * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
      13             :  *
      14             :  *
      15             :  * IDENTIFICATION
      16             :  *    src/backend/postmaster/startup.c
      17             :  *
      18             :  *-------------------------------------------------------------------------
      19             :  */
      20             : #include "postgres.h"
      21             : 
      22             : #include "access/xlog.h"
      23             : #include "libpq/pqsignal.h"
      24             : #include "miscadmin.h"
      25             : #include "pgstat.h"
      26             : #include "postmaster/interrupt.h"
      27             : #include "postmaster/startup.h"
      28             : #include "storage/ipc.h"
      29             : #include "storage/latch.h"
      30             : #include "storage/pmsignal.h"
      31             : #include "storage/procsignal.h"
      32             : #include "storage/standby.h"
      33             : #include "utils/guc.h"
      34             : #include "utils/timeout.h"
      35             : 
      36             : 
      37             : /*
      38             :  * Flags set by interrupt handlers for later service in the redo loop.
      39             :  */
      40             : static volatile sig_atomic_t got_SIGHUP = false;
      41             : static volatile sig_atomic_t shutdown_requested = false;
      42             : static volatile sig_atomic_t promote_signaled = false;
      43             : 
      44             : /*
      45             :  * Flag set when executing a restore command, to tell SIGTERM signal handler
      46             :  * that it's safe to just proc_exit.
      47             :  */
      48             : static volatile sig_atomic_t in_restore_command = false;
      49             : 
      50             : /* Signal handlers */
      51             : static void StartupProcTriggerHandler(SIGNAL_ARGS);
      52             : static void StartupProcSigHupHandler(SIGNAL_ARGS);
      53             : 
      54             : 
      55             : /* --------------------------------
      56             :  *      signal handler routines
      57             :  * --------------------------------
      58             :  */
      59             : 
      60             : /* SIGUSR2: set flag to finish recovery */
      61             : static void
      62          48 : StartupProcTriggerHandler(SIGNAL_ARGS)
      63             : {
      64          48 :     int         save_errno = errno;
      65             : 
      66          48 :     promote_signaled = true;
      67          48 :     WakeupRecovery();
      68             : 
      69          48 :     errno = save_errno;
      70          48 : }
      71             : 
      72             : /* SIGHUP: set flag to re-read config file at next convenient time */
      73             : static void
      74           6 : StartupProcSigHupHandler(SIGNAL_ARGS)
      75             : {
      76           6 :     int         save_errno = errno;
      77             : 
      78           6 :     got_SIGHUP = true;
      79           6 :     WakeupRecovery();
      80             : 
      81           6 :     errno = save_errno;
      82           6 : }
      83             : 
      84             : /* SIGTERM: set flag to abort redo and exit */
      85             : static void
      86          34 : StartupProcShutdownHandler(SIGNAL_ARGS)
      87             : {
      88          34 :     int         save_errno = errno;
      89             : 
      90          34 :     if (in_restore_command)
      91           0 :         proc_exit(1);
      92             :     else
      93          34 :         shutdown_requested = true;
      94          34 :     WakeupRecovery();
      95             : 
      96          34 :     errno = save_errno;
      97          34 : }
      98             : 
      99             : /*
     100             :  * Re-read the config file.
     101             :  *
     102             :  * If one of the critical walreceiver options has changed, flag xlog.c
     103             :  * to restart it.
     104             :  */
     105             : static void
     106           6 : StartupRereadConfig(void)
     107             : {
     108           6 :     char       *conninfo = pstrdup(PrimaryConnInfo);
     109           6 :     char       *slotname = pstrdup(PrimarySlotName);
     110           6 :     bool        tempSlot = wal_receiver_create_temp_slot;
     111             :     bool        conninfoChanged;
     112             :     bool        slotnameChanged;
     113           6 :     bool        tempSlotChanged = false;
     114             : 
     115           6 :     ProcessConfigFile(PGC_SIGHUP);
     116             : 
     117           6 :     conninfoChanged = strcmp(conninfo, PrimaryConnInfo) != 0;
     118           6 :     slotnameChanged = strcmp(slotname, PrimarySlotName) != 0;
     119             : 
     120             :     /*
     121             :      * wal_receiver_create_temp_slot is used only when we have no slot
     122             :      * configured.  We do not need to track this change if it has no effect.
     123             :      */
     124           6 :     if (!slotnameChanged && strcmp(PrimarySlotName, "") == 0)
     125           2 :         tempSlotChanged = tempSlot != wal_receiver_create_temp_slot;
     126           6 :     pfree(conninfo);
     127           6 :     pfree(slotname);
     128             : 
     129           6 :     if (conninfoChanged || slotnameChanged || tempSlotChanged)
     130           0 :         StartupRequestWalReceiverRestart();
     131           6 : }
     132             : 
     133             : /* Handle various signals that might be sent to the startup process */
     134             : void
     135      574432 : HandleStartupProcInterrupts(void)
     136             : {
     137             :     /*
     138             :      * Process any requests or signals received recently.
     139             :      */
     140      574432 :     if (got_SIGHUP)
     141             :     {
     142           6 :         got_SIGHUP = false;
     143           6 :         StartupRereadConfig();
     144             :     }
     145             : 
     146             :     /*
     147             :      * Check if we were requested to exit without finishing recovery.
     148             :      */
     149      574432 :     if (shutdown_requested)
     150          32 :         proc_exit(1);
     151             : 
     152             :     /*
     153             :      * Emergency bailout if postmaster has died.  This is to avoid the
     154             :      * necessity for manual cleanup of all postmaster children.
     155             :      */
     156      574400 :     if (IsUnderPostmaster && !PostmasterIsAlive())
     157           0 :         exit(1);
     158             : 
     159             :     /* Process barrier events */
     160      574400 :     if (ProcSignalBarrierPending)
     161           0 :         ProcessProcSignalBarrier();
     162      574400 : }
     163             : 
     164             : 
     165             : /* ----------------------------------
     166             :  *  Startup Process main entry point
     167             :  * ----------------------------------
     168             :  */
     169             : void
     170         656 : StartupProcessMain(void)
     171             : {
     172             :     /*
     173             :      * Properly accept or ignore signals the postmaster might send us.
     174             :      */
     175         656 :     pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */
     176         656 :     pqsignal(SIGINT, SIG_IGN);  /* ignore query cancel */
     177         656 :     pqsignal(SIGTERM, StartupProcShutdownHandler);  /* request shutdown */
     178         656 :     pqsignal(SIGQUIT, SignalHandlerForCrashExit);
     179         656 :     InitializeTimeouts();       /* establishes SIGALRM handler */
     180         656 :     pqsignal(SIGPIPE, SIG_IGN);
     181         656 :     pqsignal(SIGUSR1, procsignal_sigusr1_handler);
     182         656 :     pqsignal(SIGUSR2, StartupProcTriggerHandler);
     183             : 
     184             :     /*
     185             :      * Reset some signals that are accepted by postmaster but not here
     186             :      */
     187         656 :     pqsignal(SIGCHLD, SIG_DFL);
     188             : 
     189             :     /*
     190             :      * Register timeouts needed for standby mode
     191             :      */
     192         656 :     RegisterTimeout(STANDBY_DEADLOCK_TIMEOUT, StandbyDeadLockHandler);
     193         656 :     RegisterTimeout(STANDBY_TIMEOUT, StandbyTimeoutHandler);
     194         656 :     RegisterTimeout(STANDBY_LOCK_TIMEOUT, StandbyLockTimeoutHandler);
     195             : 
     196             :     /*
     197             :      * Unblock signals (they were blocked when the postmaster forked us)
     198             :      */
     199         656 :     PG_SETMASK(&UnBlockSig);
     200             : 
     201             :     /*
     202             :      * Do what we came for.
     203             :      */
     204         656 :     StartupXLOG();
     205             : 
     206             :     /*
     207             :      * Exit normally. Exit code 0 tells postmaster that we completed recovery
     208             :      * successfully.
     209             :      */
     210         622 :     proc_exit(0);
     211             : }
     212             : 
     213             : void
     214          98 : PreRestoreCommand(void)
     215             : {
     216             :     /*
     217             :      * Set in_restore_command to tell the signal handler that we should exit
     218             :      * right away on SIGTERM. We know that we're at a safe point to do that.
     219             :      * Check if we had already received the signal, so that we don't miss a
     220             :      * shutdown request received just before this.
     221             :      */
     222          98 :     in_restore_command = true;
     223          98 :     if (shutdown_requested)
     224           0 :         proc_exit(1);
     225          98 : }
     226             : 
     227             : void
     228          98 : PostRestoreCommand(void)
     229             : {
     230          98 :     in_restore_command = false;
     231          98 : }
     232             : 
     233             : bool
     234         874 : IsPromoteSignaled(void)
     235             : {
     236         874 :     return promote_signaled;
     237             : }
     238             : 
     239             : void
     240          48 : ResetPromoteSignaled(void)
     241             : {
     242          48 :     promote_signaled = false;
     243          48 : }

Generated by: LCOV version 1.13