PostgreSQL Source Code  git master
startup.c
Go to the documentation of this file.
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  */
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 */
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
96 {
97  int save_errno = errno;
98 
99  promote_signaled = true;
100  WakeupRecovery();
101 
102  errno = save_errno;
103 }
104 
105 /* SIGHUP: set flag to re-read config file at next convenient time */
106 static void
108 {
109  int save_errno = errno;
110 
111  got_SIGHUP = true;
112  WakeupRecovery();
113 
114  errno = save_errno;
115 }
116 
117 /* SIGTERM: set flag to abort redo and exit */
118 static void
120 {
121  int save_errno = errno;
122 
123  if (in_restore_command)
124  proc_exit(1);
125  else
126  shutdown_requested = true;
127  WakeupRecovery();
128 
129  errno = save_errno;
130 }
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
140 {
141  char *conninfo = pstrdup(PrimaryConnInfo);
142  char *slotname = pstrdup(PrimarySlotName);
143  bool tempSlot = wal_receiver_create_temp_slot;
144  bool conninfoChanged;
145  bool slotnameChanged;
146  bool tempSlotChanged = false;
147 
149 
150  conninfoChanged = strcmp(conninfo, PrimaryConnInfo) != 0;
151  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  if (!slotnameChanged && strcmp(PrimarySlotName, "") == 0)
158  tempSlotChanged = tempSlot != wal_receiver_create_temp_slot;
159  pfree(conninfo);
160  pfree(slotname);
161 
162  if (conninfoChanged || slotnameChanged || tempSlotChanged)
164 }
165 
166 /* Handle various signals that might be sent to the startup process */
167 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  */
177  if (got_SIGHUP)
178  {
179  got_SIGHUP = false;
181  }
182 
183  /*
184  * Check if we were requested to exit without finishing recovery.
185  */
186  if (shutdown_requested)
187  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  */
195  if (IsUnderPostmaster &&
197  postmaster_poll_count++ % POSTMASTER_POLL_RATE_LIMIT == 0 &&
198 #endif
200  exit(1);
201 
202  /* Process barrier events */
205 
206  /* Perform logging of memory contexts of this process */
209 }
210 
211 
212 /* --------------------------------
213  * signal handler routines
214  * --------------------------------
215  */
216 static void
218 {
219  /* Shutdown the recovery environment */
222 }
223 
224 
225 /* ----------------------------------
226  * Startup Process main entry point
227  * ----------------------------------
228  */
229 void
231 {
232  /* Arrange to clean up at startup process exit */
234 
235  /*
236  * Properly accept or ignore signals the postmaster might send us.
237  */
238  pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */
239  pqsignal(SIGINT, SIG_IGN); /* ignore query cancel */
240  pqsignal(SIGTERM, StartupProcShutdownHandler); /* request shutdown */
241  /* SIGQUIT handler was already set up by InitPostmasterChild */
242  InitializeTimeouts(); /* establishes SIGALRM handler */
246 
247  /*
248  * Reset some signals that are accepted by postmaster but not here
249  */
251 
252  /*
253  * Register timeouts needed for standby mode
254  */
258 
259  /*
260  * Unblock signals (they were blocked when the postmaster forked us)
261  */
262  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
263 
264  /*
265  * Do what we came for.
266  */
267  StartupXLOG();
268 
269  /*
270  * Exit normally. Exit code 0 tells postmaster that we completed recovery
271  * successfully.
272  */
273  proc_exit(0);
274 }
275 
276 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  in_restore_command = true;
286  if (shutdown_requested)
287  proc_exit(1);
288 }
289 
290 void
292 {
293  in_restore_command = false;
294 }
295 
296 bool
298 {
299  return promote_signaled;
300 }
301 
302 void
304 {
305  promote_signaled = false;
306 }
307 
308 /*
309  * Set a flag indicating that it's time to log a progress report.
310  */
311 void
313 {
315 }
316 
317 void
319 {
320  /* Feature is disabled. */
322  return;
323 
326 }
327 
328 /*
329  * Set the start timestamp of the current operation and enable the timeout.
330  */
331 void
333 {
334  TimestampTz fin_time;
335 
336  /* Feature is disabled. */
338  return;
339 
345 }
346 
347 /*
348  * A thin wrapper to first disable and then enable the startup progress
349  * timeout.
350  */
351 void
353 {
354  /* Feature is disabled. */
356  return;
357 
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
369 {
370  long seconds;
371  int useconds;
373 
374  /* No timeout has occurred. */
376  return false;
377 
378  /* Calculate the elapsed time. */
381 
382  *secs = seconds;
383  *usecs = useconds;
385 
386  return true;
387 }
sigset_t UnBlockSig
Definition: pqsignal.c:22
void HandleStartupProcInterrupts(void)
Definition: startup.c:168
void disable_startup_progress_timeout(void)
Definition: startup.c:318
#define POSTMASTER_POLL_RATE_LIMIT
Definition: startup.c:48
static volatile sig_atomic_t startup_progress_timer_expired
Definition: startup.c:73
static volatile sig_atomic_t in_restore_command
Definition: startup.c:62
static void StartupProcExit(int code, Datum arg)
Definition: startup.c:217
bool IsPromoteSignaled(void)
Definition: startup.c:297
void PreRestoreCommand(void)
Definition: startup.c:277
void startup_progress_timeout_handler(void)
Definition: startup.c:312
static volatile sig_atomic_t shutdown_requested
Definition: startup.c:55
static void StartupProcShutdownHandler(SIGNAL_ARGS)
Definition: startup.c:119
void begin_startup_progress_phase(void)
Definition: startup.c:352
void ResetPromoteSignaled(void)
Definition: startup.c:303
static void StartupProcSigHupHandler(SIGNAL_ARGS)
Definition: startup.c:107
static volatile sig_atomic_t got_SIGHUP
Definition: startup.c:54
static TimestampTz startup_progress_phase_start_time
Definition: startup.c:67
static volatile sig_atomic_t promote_signaled
Definition: startup.c:56
void PostRestoreCommand(void)
Definition: startup.c:291
static void StartupProcTriggerHandler(SIGNAL_ARGS)
Definition: startup.c:95
void StartupProcessMain(void)
Definition: startup.c:230
int log_startup_progress_interval
Definition: startup.c:78
void enable_startup_progress_timeout(void)
Definition: startup.c:332
bool has_startup_progress_timeout_expired(long *secs, int *usecs)
Definition: startup.c:368
static void StartupRereadConfig(void)
Definition: startup.c:139
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition: timestamp.c:1659
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1583
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1547
unsigned int uint32
Definition: c.h:495
#define SIGNAL_ARGS
Definition: c.h:1355
int64 TimestampTz
Definition: timestamp.h:39
volatile sig_atomic_t LogMemoryContextPending
Definition: globals.c:38
volatile sig_atomic_t ProcSignalBarrierPending
Definition: globals.c:37
bool IsUnderPostmaster
Definition: globals.c:113
@ PGC_SIGHUP
Definition: guc.h:71
void ProcessConfigFile(GucContext context)
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
void proc_exit(int code)
Definition: ipc.c:104
exit(1)
char * pstrdup(const char *in)
Definition: mcxt.c:1644
void pfree(void *pointer)
Definition: mcxt.c:1456
void ProcessLogMemoryContextInterrupt(void)
Definition: mcxt.c:1199
void * arg
#define PostmasterIsAlive()
Definition: pmsignal.h:102
pqsigfunc pqsignal(int signo, pqsigfunc func)
uintptr_t Datum
Definition: postgres.h:64
void ProcessProcSignalBarrier(void)
Definition: procsignal.c:468
void procsignal_sigusr1_handler(SIGNAL_ARGS)
Definition: procsignal.c:639
void StandbyTimeoutHandler(void)
Definition: standby.c:945
void StandbyLockTimeoutHandler(void)
Definition: standby.c:954
void StandbyDeadLockHandler(void)
Definition: standby.c:936
void ShutdownRecoveryTransactionEnvironment(void)
Definition: standby.c:161
void InitializeTimeouts(void)
Definition: timeout.c:474
void enable_timeout_every(TimeoutId id, TimestampTz fin_time, int delay_ms)
Definition: timeout.c:588
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:689
TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler)
Definition: timeout.c:509
@ STARTUP_PROGRESS_TIMEOUT
Definition: timeout.h:37
@ STANDBY_LOCK_TIMEOUT
Definition: timeout.h:32
@ STANDBY_DEADLOCK_TIMEOUT
Definition: timeout.h:30
@ STANDBY_TIMEOUT
Definition: timeout.h:31
#define TimestampTzPlusMilliseconds(tz, ms)
Definition: timestamp.h:85
#define SIGCHLD
Definition: win32_port.h:178
#define SIGHUP
Definition: win32_port.h:168
#define SIG_DFL
Definition: win32_port.h:163
#define SIGPIPE
Definition: win32_port.h:173
#define SIGUSR1
Definition: win32_port.h:180
#define SIGUSR2
Definition: win32_port.h:181
#define SIG_IGN
Definition: win32_port.h:165
void StartupXLOG(void)
Definition: xlog.c:5056
void StartupRequestWalReceiverRestart(void)
char * PrimarySlotName
Definition: xlogrecovery.c:97
void WakeupRecovery(void)
bool wal_receiver_create_temp_slot
Definition: xlogrecovery.c:98
char * PrimaryConnInfo
Definition: xlogrecovery.c:96
HotStandbyState standbyState
Definition: xlogutils.c:56
@ STANDBY_DISABLED
Definition: xlogutils.h:49