LCOV - differential code coverage report
Current view: top level - src/backend/postmaster - startup.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 86.4 % 110 95 15 1 94 1
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 16 16 1 15
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 83.3 % 12 10 2 1 9
Legend: Lines: hit not hit (240..) days: 86.7 % 98 85 13 85
Function coverage date bins:
(60,120] days: 100.0 % 3 3 3
(240..) days: 100.0 % 13 13 1 12

 Age         Owner                  TLA  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-2023, 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 "access/xlogrecovery.h"
                                 24                 : #include "access/xlogutils.h"
                                 25                 : #include "libpq/pqsignal.h"
                                 26                 : #include "miscadmin.h"
                                 27                 : #include "pgstat.h"
                                 28                 : #include "postmaster/interrupt.h"
                                 29                 : #include "postmaster/startup.h"
                                 30                 : #include "storage/ipc.h"
                                 31                 : #include "storage/latch.h"
                                 32                 : #include "storage/pmsignal.h"
                                 33                 : #include "storage/procsignal.h"
                                 34                 : #include "storage/standby.h"
                                 35                 : #include "utils/guc.h"
                                 36                 : #include "utils/memutils.h"
                                 37                 : #include "utils/timeout.h"
                                 38                 : 
                                 39                 : 
                                 40                 : #ifndef USE_POSTMASTER_DEATH_SIGNAL
                                 41                 : /*
                                 42                 :  * On systems that need to make a system call to find out if the postmaster has
                                 43                 :  * gone away, we'll do so only every Nth call to HandleStartupProcInterrupts().
                                 44                 :  * This only affects how long it takes us to detect the condition while we're
                                 45                 :  * busy replaying WAL.  Latch waits and similar which should react immediately
                                 46                 :  * through the usual techniques.
                                 47                 :  */
                                 48                 : #define POSTMASTER_POLL_RATE_LIMIT 1024
                                 49                 : #endif
                                 50                 : 
                                 51                 : /*
                                 52                 :  * Flags set by interrupt handlers for later service in the redo loop.
                                 53                 :  */
                                 54                 : static volatile sig_atomic_t got_SIGHUP = false;
                                 55                 : static volatile sig_atomic_t shutdown_requested = false;
                                 56                 : static volatile sig_atomic_t promote_signaled = false;
                                 57                 : 
                                 58                 : /*
                                 59                 :  * Flag set when executing a restore command, to tell SIGTERM signal handler
                                 60                 :  * that it's safe to just proc_exit.
                                 61                 :  */
                                 62                 : static volatile sig_atomic_t in_restore_command = false;
                                 63                 : 
                                 64                 : /*
                                 65                 :  * Time at which the most recent startup operation started.
                                 66                 :  */
                                 67                 : static TimestampTz startup_progress_phase_start_time;
                                 68                 : 
                                 69                 : /*
                                 70                 :  * Indicates whether the startup progress interval mentioned by the user is
                                 71                 :  * elapsed or not. TRUE if timeout occurred, FALSE otherwise.
                                 72                 :  */
                                 73                 : static volatile sig_atomic_t startup_progress_timer_expired = false;
                                 74                 : 
                                 75                 : /*
                                 76                 :  * Time between progress updates for long-running startup operations.
                                 77                 :  */
                                 78                 : int         log_startup_progress_interval = 10000;  /* 10 sec */
                                 79                 : 
                                 80                 : /* Signal handlers */
                                 81                 : static void StartupProcTriggerHandler(SIGNAL_ARGS);
                                 82                 : static void StartupProcSigHupHandler(SIGNAL_ARGS);
                                 83                 : 
                                 84                 : /* Callbacks */
                                 85                 : static void StartupProcExit(int code, Datum arg);
                                 86                 : 
                                 87                 : 
                                 88                 : /* --------------------------------
                                 89                 :  *      signal handler routines
                                 90                 :  * --------------------------------
                                 91                 :  */
                                 92                 : 
                                 93                 : /* SIGUSR2: set flag to finish recovery */
                                 94                 : static void
 4176 simon                      95 CBC          36 : StartupProcTriggerHandler(SIGNAL_ARGS)
                                 96                 : {
                                 97              36 :     int         save_errno = errno;
                                 98                 : 
 1111 fujii                      99              36 :     promote_signaled = true;
  843                           100              36 :     WakeupRecovery();
                                101                 : 
                                102              36 :     errno = save_errno;
                                103              36 : }
                                104                 : 
                                105                 : /* SIGHUP: set flag to re-read config file at next convenient time */
                                106                 : static void
                                107              14 : StartupProcSigHupHandler(SIGNAL_ARGS)
                                108                 : {
                                109              14 :     int         save_errno = errno;
                                110                 : 
                                111              14 :     got_SIGHUP = true;
                                112              14 :     WakeupRecovery();
                                113                 : 
 4176 simon                     114              14 :     errno = save_errno;
                                115              14 : }
                                116                 : 
                                117                 : /* SIGTERM: set flag to abort redo and exit */
                                118                 : static void
                                119              31 : StartupProcShutdownHandler(SIGNAL_ARGS)
                                120                 : {
                                121              31 :     int         save_errno = errno;
                                122                 : 
                                123              31 :     if (in_restore_command)
 4176 simon                     124 UBC           0 :         proc_exit(1);
                                125                 :     else
 4176 simon                     126 CBC          31 :         shutdown_requested = true;
  843 fujii                     127              31 :     WakeupRecovery();
                                128                 : 
 4176 simon                     129              31 :     errno = save_errno;
                                130              31 : }
                                131                 : 
                                132                 : /*
                                133                 :  * Re-read the config file.
                                134                 :  *
                                135                 :  * If one of the critical walreceiver options has changed, flag xlog.c
                                136                 :  * to restart it.
                                137                 :  */
                                138                 : static void
 1108 alvherre                  139              14 : StartupRereadConfig(void)
                                140                 : {
                                141              14 :     char       *conninfo = pstrdup(PrimaryConnInfo);
                                142              14 :     char       *slotname = pstrdup(PrimarySlotName);
                                143              14 :     bool        tempSlot = wal_receiver_create_temp_slot;
                                144                 :     bool        conninfoChanged;
                                145                 :     bool        slotnameChanged;
                                146              14 :     bool        tempSlotChanged = false;
                                147                 : 
                                148              14 :     ProcessConfigFile(PGC_SIGHUP);
                                149                 : 
                                150              14 :     conninfoChanged = strcmp(conninfo, PrimaryConnInfo) != 0;
                                151              14 :     slotnameChanged = strcmp(slotname, PrimarySlotName) != 0;
                                152                 : 
                                153                 :     /*
                                154                 :      * wal_receiver_create_temp_slot is used only when we have no slot
                                155                 :      * configured.  We do not need to track this change if it has no effect.
                                156                 :      */
                                157              14 :     if (!slotnameChanged && strcmp(PrimarySlotName, "") == 0)
                                158               3 :         tempSlotChanged = tempSlot != wal_receiver_create_temp_slot;
                                159              14 :     pfree(conninfo);
                                160              14 :     pfree(slotname);
                                161                 : 
                                162              14 :     if (conninfoChanged || slotnameChanged || tempSlotChanged)
 1108 alvherre                  163 UBC           0 :         StartupRequestWalReceiverRestart();
 1108 alvherre                  164 CBC          14 : }
                                165                 : 
                                166                 : /* Handle various signals that might be sent to the startup process */
                                167                 : void
 4176 simon                     168         2517486 : HandleStartupProcInterrupts(void)
                                169                 : {
                                170                 : #ifdef POSTMASTER_POLL_RATE_LIMIT
                                171                 :     static uint32 postmaster_poll_count = 0;
                                172                 : #endif
                                173                 : 
                                174                 :     /*
                                175                 :      * Process any requests or signals received recently.
                                176                 :      */
  843 fujii                     177         2517486 :     if (got_SIGHUP)
                                178                 :     {
                                179              14 :         got_SIGHUP = false;
 1108 alvherre                  180              14 :         StartupRereadConfig();
                                181                 :     }
                                182                 : 
                                183                 :     /*
                                184                 :      * Check if we were requested to exit without finishing recovery.
                                185                 :      */
 4176 simon                     186         2517486 :     if (shutdown_requested)
                                187              31 :         proc_exit(1);
                                188                 : 
                                189                 :     /*
                                190                 :      * Emergency bailout if postmaster has died.  This is to avoid the
                                191                 :      * necessity for manual cleanup of all postmaster children.  Do this less
                                192                 :      * frequently on systems for which we don't have signals to make that
                                193                 :      * cheap.
                                194                 :      */
  758 tmunro                    195         2517455 :     if (IsUnderPostmaster &&
                                196                 : #ifdef POSTMASTER_POLL_RATE_LIMIT
                                197                 :         postmaster_poll_count++ % POSTMASTER_POLL_RATE_LIMIT == 0 &&
                                198                 : #endif
                                199         2491932 :         !PostmasterIsAlive())
 4176 simon                     200 UBC           0 :         exit(1);
                                201                 : 
                                202                 :     /* Process barrier events */
 1207 rhaas                     203 CBC     2517455 :     if (ProcSignalBarrierPending)
 1207 rhaas                     204 UBC           0 :         ProcessProcSignalBarrier();
                                205                 : 
                                206                 :     /* Perform logging of memory contexts of this process */
  453 fujii                     207 CBC     2517455 :     if (LogMemoryContextPending)
  453 fujii                     208 UBC           0 :         ProcessLogMemoryContextInterrupt();
 4176 simon                     209 CBC     2517455 : }
                                210                 : 
                                211                 : 
                                212                 : /* --------------------------------
                                213                 :  *      signal handler routines
                                214                 :  * --------------------------------
                                215                 :  */
                                216                 : static void
  733 fujii                     217             557 : StartupProcExit(int code, Datum arg)
                                218                 : {
                                219                 :     /* Shutdown the recovery environment */
                                220             557 :     if (standbyState != STANDBY_DISABLED)
                                221              71 :         ShutdownRecoveryTransactionEnvironment();
                                222             557 : }
                                223                 : 
                                224                 : 
                                225                 : /* ----------------------------------
                                226                 :  *  Startup Process main entry point
                                227                 :  * ----------------------------------
                                228                 :  */
                                229                 : void
 4176 simon                     230             557 : StartupProcessMain(void)
                                231                 : {
                                232                 :     /* Arrange to clean up at startup process exit */
  733 fujii                     233             557 :     on_shmem_exit(StartupProcExit, 0);
                                234                 : 
                                235                 :     /*
                                236                 :      * Properly accept or ignore signals the postmaster might send us.
                                237                 :      */
  843                           238             557 :     pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */
 4176 simon                     239             557 :     pqsignal(SIGINT, SIG_IGN);  /* ignore query cancel */
 2118 tgl                       240             557 :     pqsignal(SIGTERM, StartupProcShutdownHandler);  /* request shutdown */
                                241                 :     /* SIGQUIT handler was already set up by InitPostmasterChild */
 3919 alvherre                  242             557 :     InitializeTimeouts();       /* establishes SIGALRM handler */
 4176 simon                     243             557 :     pqsignal(SIGPIPE, SIG_IGN);
 1231 rhaas                     244             557 :     pqsignal(SIGUSR1, procsignal_sigusr1_handler);
 4176 simon                     245             557 :     pqsignal(SIGUSR2, StartupProcTriggerHandler);
                                246                 : 
                                247                 :     /*
                                248                 :      * Reset some signals that are accepted by postmaster but not here
                                249                 :      */
                                250             557 :     pqsignal(SIGCHLD, SIG_DFL);
                                251                 : 
                                252                 :     /*
                                253                 :      * Register timeouts needed for standby mode
                                254                 :      */
 3919 alvherre                  255             557 :     RegisterTimeout(STANDBY_DEADLOCK_TIMEOUT, StandbyDeadLockHandler);
                                256             557 :     RegisterTimeout(STANDBY_TIMEOUT, StandbyTimeoutHandler);
 2586 simon                     257             557 :     RegisterTimeout(STANDBY_LOCK_TIMEOUT, StandbyLockTimeoutHandler);
                                258                 : 
                                259                 :     /*
                                260                 :      * Unblock signals (they were blocked when the postmaster forked us)
                                261                 :      */
   65 tmunro                    262 GNC         557 :     sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
                                263                 : 
                                264                 :     /*
                                265                 :      * Do what we came for.
                                266                 :      */
 4176 simon                     267 CBC         557 :     StartupXLOG();
                                268                 : 
                                269                 :     /*
                                270                 :      * Exit normally. Exit code 0 tells postmaster that we completed recovery
                                271                 :      * successfully.
                                272                 :      */
                                273             523 :     proc_exit(0);
                                274                 : }
                                275                 : 
                                276                 : void
                                277             131 : PreRestoreCommand(void)
                                278                 : {
                                279                 :     /*
                                280                 :      * Set in_restore_command to tell the signal handler that we should exit
                                281                 :      * right away on SIGTERM. We know that we're at a safe point to do that.
                                282                 :      * Check if we had already received the signal, so that we don't miss a
                                283                 :      * shutdown request received just before this.
                                284                 :      */
                                285             131 :     in_restore_command = true;
                                286             131 :     if (shutdown_requested)
 4176 simon                     287 UBC           0 :         proc_exit(1);
 4176 simon                     288 CBC         131 : }
                                289                 : 
                                290                 : void
                                291             131 : PostRestoreCommand(void)
                                292                 : {
                                293             131 :     in_restore_command = false;
                                294             131 : }
                                295                 : 
                                296                 : bool
 1111 fujii                     297           13211 : IsPromoteSignaled(void)
                                298                 : {
                                299           13211 :     return promote_signaled;
                                300                 : }
                                301                 : 
                                302                 : void
                                303              36 : ResetPromoteSignaled(void)
                                304                 : {
                                305              36 :     promote_signaled = false;
 4176 simon                     306              36 : }
                                307                 : 
                                308                 : /*
                                309                 :  * Set a flag indicating that it's time to log a progress report.
                                310                 :  */
                                311                 : void
  531 rhaas                     312              10 : startup_progress_timeout_handler(void)
                                313                 : {
                                314              10 :     startup_progress_timer_expired = true;
                                315              10 : }
                                316                 : 
                                317                 : void
   62                           318             414 : disable_startup_progress_timeout(void)
                                319                 : {
                                320                 :     /* Feature is disabled. */
                                321             414 :     if (log_startup_progress_interval == 0)
   62 rhaas                     322 UBC           0 :         return;
                                323                 : 
   62 rhaas                     324 CBC         414 :     disable_timeout(STARTUP_PROGRESS_TIMEOUT, false);
                                325             414 :     startup_progress_timer_expired = false;
                                326                 : }
                                327                 : 
                                328                 : /*
                                329                 :  * Set the start timestamp of the current operation and enable the timeout.
                                330                 :  */
                                331                 : void
                                332             346 : enable_startup_progress_timeout(void)
                                333                 : {
                                334                 :     TimestampTz fin_time;
                                335                 : 
                                336                 :     /* Feature is disabled. */
  531                           337             346 :     if (log_startup_progress_interval == 0)
  531 rhaas                     338 UBC           0 :         return;
                                339                 : 
  531 rhaas                     340 CBC         346 :     startup_progress_phase_start_time = GetCurrentTimestamp();
                                341             346 :     fin_time = TimestampTzPlusMilliseconds(startup_progress_phase_start_time,
                                342                 :                                            log_startup_progress_interval);
                                343             346 :     enable_timeout_every(STARTUP_PROGRESS_TIMEOUT, fin_time,
                                344                 :                          log_startup_progress_interval);
                                345                 : }
                                346                 : 
                                347                 : /*
                                348                 :  * A thin wrapper to first disable and then enable the startup progress
                                349                 :  * timeout.
                                350                 :  */
                                351                 : void
   62                           352             346 : begin_startup_progress_phase(void)
                                353                 : {
                                354                 :     /* Feature is disabled. */
                                355             346 :     if (log_startup_progress_interval == 0)
   62 rhaas                     356 UBC           0 :         return;
                                357                 : 
   62 rhaas                     358 CBC         346 :     disable_startup_progress_timeout();
                                359             346 :     enable_startup_progress_timeout();
                                360                 : }
                                361                 : 
                                362                 : /*
                                363                 :  * Report whether startup progress timeout has occurred. Reset the timer flag
                                364                 :  * if it did, set the elapsed time to the out parameters and return true,
                                365                 :  * otherwise return false.
                                366                 :  */
                                367                 : bool
  531                           368          239346 : has_startup_progress_timeout_expired(long *secs, int *usecs)
                                369                 : {
                                370                 :     long        seconds;
                                371                 :     int         useconds;
                                372                 :     TimestampTz now;
                                373                 : 
                                374                 :     /* No timeout has occurred. */
                                375          239346 :     if (!startup_progress_timer_expired)
                                376          239346 :         return false;
                                377                 : 
                                378                 :     /* Calculate the elapsed time. */
  531 rhaas                     379 UBC           0 :     now = GetCurrentTimestamp();
                                380               0 :     TimestampDifference(startup_progress_phase_start_time, now, &seconds, &useconds);
                                381                 : 
                                382               0 :     *secs = seconds;
                                383               0 :     *usecs = useconds;
                                384               0 :     startup_progress_timer_expired = false;
                                385                 : 
                                386               0 :     return true;
                                387                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a