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-2021, 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/xlogutils.h"
24 #include "libpq/pqsignal.h"
25 #include "miscadmin.h"
26 #include "pgstat.h"
27 #include "postmaster/interrupt.h"
28 #include "postmaster/startup.h"
29 #include "storage/ipc.h"
30 #include "storage/latch.h"
31 #include "storage/pmsignal.h"
32 #include "storage/procsignal.h"
33 #include "storage/standby.h"
34 #include "utils/guc.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  */
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 */
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
94 {
95  int save_errno = errno;
96 
97  promote_signaled = true;
99 
100  errno = save_errno;
101 }
102 
103 /* SIGHUP: set flag to re-read config file at next convenient time */
104 static void
106 {
107  int save_errno = errno;
108 
109  got_SIGHUP = true;
110  WakeupRecovery();
111 
112  errno = save_errno;
113 }
114 
115 /* SIGTERM: set flag to abort redo and exit */
116 static void
118 {
119  int save_errno = errno;
120 
121  if (in_restore_command)
122  proc_exit(1);
123  else
124  shutdown_requested = true;
125  WakeupRecovery();
126 
127  errno = save_errno;
128 }
129 
130 /*
131  * Re-read the config file.
132  *
133  * If one of the critical walreceiver options has changed, flag xlog.c
134  * to restart it.
135  */
136 static void
138 {
139  char *conninfo = pstrdup(PrimaryConnInfo);
140  char *slotname = pstrdup(PrimarySlotName);
141  bool tempSlot = wal_receiver_create_temp_slot;
142  bool conninfoChanged;
143  bool slotnameChanged;
144  bool tempSlotChanged = false;
145 
147 
148  conninfoChanged = strcmp(conninfo, PrimaryConnInfo) != 0;
149  slotnameChanged = strcmp(slotname, PrimarySlotName) != 0;
150 
151  /*
152  * wal_receiver_create_temp_slot is used only when we have no slot
153  * configured. We do not need to track this change if it has no effect.
154  */
155  if (!slotnameChanged && strcmp(PrimarySlotName, "") == 0)
156  tempSlotChanged = tempSlot != wal_receiver_create_temp_slot;
157  pfree(conninfo);
158  pfree(slotname);
159 
160  if (conninfoChanged || slotnameChanged || tempSlotChanged)
162 }
163 
164 /* Handle various signals that might be sent to the startup process */
165 void
167 {
168 #ifdef POSTMASTER_POLL_RATE_LIMIT
169  static uint32 postmaster_poll_count = 0;
170 #endif
171 
172  /*
173  * Process any requests or signals received recently.
174  */
175  if (got_SIGHUP)
176  {
177  got_SIGHUP = false;
179  }
180 
181  /*
182  * Check if we were requested to exit without finishing recovery.
183  */
184  if (shutdown_requested)
185  proc_exit(1);
186 
187  /*
188  * Emergency bailout if postmaster has died. This is to avoid the
189  * necessity for manual cleanup of all postmaster children. Do this less
190  * frequently on systems for which we don't have signals to make that
191  * cheap.
192  */
193  if (IsUnderPostmaster &&
195  postmaster_poll_count++ % POSTMASTER_POLL_RATE_LIMIT == 0 &&
196 #endif
198  exit(1);
199 
200  /* Process barrier events */
203 }
204 
205 
206 /* --------------------------------
207  * signal handler routines
208  * --------------------------------
209  */
210 static void
212 {
213  /* Shutdown the recovery environment */
216 }
217 
218 
219 /* ----------------------------------
220  * Startup Process main entry point
221  * ----------------------------------
222  */
223 void
225 {
226  /* Arrange to clean up at startup process exit */
228 
229  /*
230  * Properly accept or ignore signals the postmaster might send us.
231  */
232  pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */
233  pqsignal(SIGINT, SIG_IGN); /* ignore query cancel */
234  pqsignal(SIGTERM, StartupProcShutdownHandler); /* request shutdown */
235  /* SIGQUIT handler was already set up by InitPostmasterChild */
236  InitializeTimeouts(); /* establishes SIGALRM handler */
240 
241  /*
242  * Reset some signals that are accepted by postmaster but not here
243  */
245 
246  /*
247  * Register timeouts needed for standby mode
248  */
252 
253  /*
254  * Unblock signals (they were blocked when the postmaster forked us)
255  */
257 
258  /*
259  * Do what we came for.
260  */
261  StartupXLOG();
262 
263  /*
264  * Exit normally. Exit code 0 tells postmaster that we completed recovery
265  * successfully.
266  */
267  proc_exit(0);
268 }
269 
270 void
272 {
273  /*
274  * Set in_restore_command to tell the signal handler that we should exit
275  * right away on SIGTERM. We know that we're at a safe point to do that.
276  * Check if we had already received the signal, so that we don't miss a
277  * shutdown request received just before this.
278  */
279  in_restore_command = true;
280  if (shutdown_requested)
281  proc_exit(1);
282 }
283 
284 void
286 {
287  in_restore_command = false;
288 }
289 
290 bool
292 {
293  return promote_signaled;
294 }
295 
296 void
298 {
299  promote_signaled = false;
300 }
301 
302 /*
303  * Set a flag indicating that it's time to log a progress report.
304  */
305 void
307 {
309 }
310 
311 /*
312  * Set the start timestamp of the current operation and enable the timeout.
313  */
314 void
316 {
317  TimestampTz fin_time;
318 
319  /* Feature is disabled. */
321  return;
322 
330 }
331 
332 /*
333  * Report whether startup progress timeout has occurred. Reset the timer flag
334  * if it did, set the elapsed time to the out parameters and return true,
335  * otherwise return false.
336  */
337 bool
339 {
340  long seconds;
341  int useconds;
343 
344  /* No timeout has occurred. */
346  return false;
347 
348  /* Calculate the elapsed time. */
351 
352  *secs = seconds;
353  *usecs = useconds;
355 
356  return true;
357 }
sigset_t UnBlockSig
Definition: pqsignal.c:22
void HandleStartupProcInterrupts(void)
Definition: startup.c:166
#define POSTMASTER_POLL_RATE_LIMIT
Definition: startup.c:46
static volatile sig_atomic_t startup_progress_timer_expired
Definition: startup.c:71
static volatile sig_atomic_t in_restore_command
Definition: startup.c:60
static void StartupProcExit(int code, Datum arg)
Definition: startup.c:211
bool IsPromoteSignaled(void)
Definition: startup.c:291
void PreRestoreCommand(void)
Definition: startup.c:271
void startup_progress_timeout_handler(void)
Definition: startup.c:306
static volatile sig_atomic_t shutdown_requested
Definition: startup.c:53
static void StartupProcShutdownHandler(SIGNAL_ARGS)
Definition: startup.c:117
void begin_startup_progress_phase(void)
Definition: startup.c:315
void ResetPromoteSignaled(void)
Definition: startup.c:297
static void StartupProcSigHupHandler(SIGNAL_ARGS)
Definition: startup.c:105
static volatile sig_atomic_t got_SIGHUP
Definition: startup.c:52
static TimestampTz startup_progress_phase_start_time
Definition: startup.c:65
static volatile sig_atomic_t promote_signaled
Definition: startup.c:54
void PostRestoreCommand(void)
Definition: startup.c:285
static void StartupProcTriggerHandler(SIGNAL_ARGS)
Definition: startup.c:93
void StartupProcessMain(void)
Definition: startup.c:224
int log_startup_progress_interval
Definition: startup.c:76
bool has_startup_progress_timeout_expired(long *secs, int *usecs)
Definition: startup.c:338
static void StartupRereadConfig(void)
Definition: startup.c:137
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition: timestamp.c:1656
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1580
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1544
unsigned int uint32
Definition: c.h:441
#define SIGNAL_ARGS
Definition: c.h:1342
int64 TimestampTz
Definition: timestamp.h:39
volatile sig_atomic_t ProcSignalBarrierPending
Definition: globals.c:37
bool IsUnderPostmaster
Definition: globals.c:112
@ PGC_SIGHUP
Definition: guc.h:72
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:1299
void pfree(void *pointer)
Definition: mcxt.c:1169
void * arg
#define PostmasterIsAlive()
Definition: pmsignal.h:102
uintptr_t Datum
Definition: postgres.h:411
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
void ProcessProcSignalBarrier(void)
Definition: procsignal.c:453
void procsignal_sigusr1_handler(SIGNAL_ARGS)
Definition: procsignal.c:642
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
void StandbyTimeoutHandler(void)
Definition: standby.c:904
void StandbyLockTimeoutHandler(void)
Definition: standby.c:916
void StandbyDeadLockHandler(void)
Definition: standby.c:893
void ShutdownRecoveryTransactionEnvironment(void)
Definition: standby.c:138
void InitializeTimeouts(void)
Definition: timeout.c:461
void enable_timeout_every(TimeoutId id, TimestampTz fin_time, int delay_ms)
Definition: timeout.c:575
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:676
TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler)
Definition: timeout.c:496
@ STARTUP_PROGRESS_TIMEOUT
Definition: timeout.h:36
@ 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:56
#define SIGCHLD
Definition: win32_port.h:177
#define SIGHUP
Definition: win32_port.h:167
#define SIG_DFL
Definition: win32_port.h:162
#define SIGPIPE
Definition: win32_port.h:172
#define SIGUSR1
Definition: win32_port.h:179
#define SIGUSR2
Definition: win32_port.h:180
#define SIG_IGN
Definition: win32_port.h:164
void StartupXLOG(void)
Definition: xlog.c:6668
void StartupRequestWalReceiverRestart(void)
Definition: xlog.c:13088
char * PrimarySlotName
Definition: xlog.c:284
void WakeupRecovery(void)
Definition: xlog.c:13254
bool wal_receiver_create_temp_slot
Definition: xlog.c:286
char * PrimaryConnInfo
Definition: xlog.c:283
HotStandbyState standbyState
Definition: xlogutils.c:55
@ STANDBY_DISABLED
Definition: xlogutils.h:49