1/*-------------------------------------------------------------------------
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,
12 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
16 * src/backend/postmaster/startup.c
18 *-------------------------------------------------------------------------
38#ifndef USE_POSTMASTER_DEATH_SIGNAL
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 ProcessStartupProcInterrupts().
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.
46 #define POSTMASTER_POLL_RATE_LIMIT 1024
50 * Flags set by interrupt handlers for later service in the redo loop.
57 * Flag set when executing a restore command, to tell SIGTERM signal handler
58 * that it's safe to just proc_exit.
63 * Time at which the most recent startup operation started.
68 * Indicates whether the startup progress interval mentioned by the user is
69 * elapsed or not. TRUE if timeout occurred, FALSE otherwise.
74 * Time between progress updates for long-running startup operations.
86/* --------------------------------
87 * signal handler routines
88 * --------------------------------
91/* SIGUSR2: set flag to finish recovery */
99/* SIGHUP: set flag to re-read config file at next convenient time */
107/* SIGTERM: set flag to abort redo and exit */
119 * Re-read the config file.
121 * If one of the critical walreceiver options has changed, flag xlog.c
130 bool conninfoChanged;
131 bool slotnameChanged;
132 bool tempSlotChanged =
false;
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.
148 if (conninfoChanged || slotnameChanged || tempSlotChanged)
152/* Process various signals that might be sent to the startup process */
156#ifdef POSTMASTER_POLL_RATE_LIMIT
157 static uint32 postmaster_poll_count = 0;
161 * Process any requests or signals received recently.
170 * Check if we were requested to exit without finishing recovery.
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
188 /* Process barrier events */
192 /* Perform logging of memory contexts of this process */
198/* --------------------------------
199 * signal handler routines
200 * --------------------------------
205 /* Shutdown the recovery environment */
211/* ----------------------------------
212 * Startup Process main entry point
213 * ----------------------------------
218 Assert(startup_data_len == 0);
223 /* Arrange to clean up at startup process exit */
227 * Properly accept or ignore signals the postmaster might send us.
230 pqsignal(SIGINT, SIG_IGN);
/* ignore query cancel */
232 /* SIGQUIT handler was already set up by InitPostmasterChild */
239 * Reset some signals that are accepted by postmaster but not here
244 * Register timeouts needed for standby mode
251 * Unblock signals (they were blocked when the postmaster forked us)
256 * Do what we came for.
261 * Exit normally. Exit code 0 tells postmaster that we completed recovery
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.
300 * Set a flag indicating that it's time to log a progress report.
311 /* Feature is disabled. */
320 * Set the start timestamp of the current operation and enable the timeout.
327 /* Feature is disabled. */
339 * A thin wrapper to first disable and then enable the startup progress
345 /* Feature is disabled. */
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.
365 /* No timeout has occurred. */
369 /* Calculate the elapsed time. */
void AuxiliaryProcessMainCommon(void)
void disable_startup_progress_timeout(void)
#define POSTMASTER_POLL_RATE_LIMIT
static volatile sig_atomic_t startup_progress_timer_expired
static volatile sig_atomic_t in_restore_command
static void StartupProcExit(int code, Datum arg)
bool IsPromoteSignaled(void)
void PreRestoreCommand(void)
void startup_progress_timeout_handler(void)
static volatile sig_atomic_t shutdown_requested
static void StartupProcShutdownHandler(SIGNAL_ARGS)
void begin_startup_progress_phase(void)
void ProcessStartupProcInterrupts(void)
void ResetPromoteSignaled(void)
static void StartupProcSigHupHandler(SIGNAL_ARGS)
static volatile sig_atomic_t got_SIGHUP
static TimestampTz startup_progress_phase_start_time
static volatile sig_atomic_t promote_signaled
void PostRestoreCommand(void)
static void StartupProcTriggerHandler(SIGNAL_ARGS)
void StartupProcessMain(const void *startup_data, size_t startup_data_len)
int log_startup_progress_interval
void enable_startup_progress_timeout(void)
bool has_startup_progress_timeout_expired(long *secs, int *usecs)
static void StartupRereadConfig(void)
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
TimestampTz GetCurrentTimestamp(void)
Datum now(PG_FUNCTION_ARGS)
volatile sig_atomic_t LogMemoryContextPending
volatile sig_atomic_t ProcSignalBarrierPending
void ProcessConfigFile(GucContext context)
Assert(PointerIsAligned(start, uint64))
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
char * pstrdup(const char *in)
void pfree(void *pointer)
void ProcessLogMemoryContextInterrupt(void)
BackendType MyBackendType
#define PostmasterIsAlive()
void ProcessProcSignalBarrier(void)
void procsignal_sigusr1_handler(SIGNAL_ARGS)
void StandbyTimeoutHandler(void)
void StandbyLockTimeoutHandler(void)
void StandbyDeadLockHandler(void)
void ShutdownRecoveryTransactionEnvironment(void)
void InitializeTimeouts(void)
void enable_timeout_every(TimeoutId id, TimestampTz fin_time, int delay_ms)
void disable_timeout(TimeoutId id, bool keep_indicator)
TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler)
@ STARTUP_PROGRESS_TIMEOUT
@ STANDBY_DEADLOCK_TIMEOUT
#define TimestampTzPlusMilliseconds(tz, ms)
void StartupRequestWalReceiverRestart(void)
void WakeupRecovery(void)
bool wal_receiver_create_temp_slot
HotStandbyState standbyState