LCOV - differential code coverage report
Current view: top level - src/backend/postmaster - startup.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 86.9 % 107 93 1 13 4 89 4 7
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 16 16 4 12 1
Baseline: 16@8cea358b128 Branches: 71.1 % 38 27 1 10 1 26
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed [..60] days: 80.0 % 5 4 1 4
(240..) days: 87.3 % 102 89 13 89
Function coverage date bins:
[..60] days: 100.0 % 1 1 1
(240..) days: 100.0 % 15 15 3 12
Branch coverage date bins:
[..60] days: 50.0 % 2 1 1 1
(240..) days: 72.2 % 36 26 10 26

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

Generated by: LCOV version 2.1-beta2-3-g6141622