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 /* Signal handlers */
65 
66 /* Callbacks */
67 static void StartupProcExit(int code, Datum arg);
68 
69 
70 /* --------------------------------
71  * signal handler routines
72  * --------------------------------
73  */
74 
75 /* SIGUSR2: set flag to finish recovery */
76 static void
78 {
79  int save_errno = errno;
80 
81  promote_signaled = true;
83 
84  errno = save_errno;
85 }
86 
87 /* SIGHUP: set flag to re-read config file at next convenient time */
88 static void
90 {
91  int save_errno = errno;
92 
93  got_SIGHUP = true;
95 
96  errno = save_errno;
97 }
98 
99 /* SIGTERM: set flag to abort redo and exit */
100 static void
102 {
103  int save_errno = errno;
104 
105  if (in_restore_command)
106  proc_exit(1);
107  else
108  shutdown_requested = true;
109  WakeupRecovery();
110 
111  errno = save_errno;
112 }
113 
114 /*
115  * Re-read the config file.
116  *
117  * If one of the critical walreceiver options has changed, flag xlog.c
118  * to restart it.
119  */
120 static void
122 {
123  char *conninfo = pstrdup(PrimaryConnInfo);
124  char *slotname = pstrdup(PrimarySlotName);
125  bool tempSlot = wal_receiver_create_temp_slot;
126  bool conninfoChanged;
127  bool slotnameChanged;
128  bool tempSlotChanged = false;
129 
131 
132  conninfoChanged = strcmp(conninfo, PrimaryConnInfo) != 0;
133  slotnameChanged = strcmp(slotname, PrimarySlotName) != 0;
134 
135  /*
136  * wal_receiver_create_temp_slot is used only when we have no slot
137  * configured. We do not need to track this change if it has no effect.
138  */
139  if (!slotnameChanged && strcmp(PrimarySlotName, "") == 0)
140  tempSlotChanged = tempSlot != wal_receiver_create_temp_slot;
141  pfree(conninfo);
142  pfree(slotname);
143 
144  if (conninfoChanged || slotnameChanged || tempSlotChanged)
146 }
147 
148 /* Handle various signals that might be sent to the startup process */
149 void
151 {
152 #ifdef POSTMASTER_POLL_RATE_LIMIT
153  static uint32 postmaster_poll_count = 0;
154 #endif
155 
156  /*
157  * Process any requests or signals received recently.
158  */
159  if (got_SIGHUP)
160  {
161  got_SIGHUP = false;
163  }
164 
165  /*
166  * Check if we were requested to exit without finishing recovery.
167  */
168  if (shutdown_requested)
169  proc_exit(1);
170 
171  /*
172  * Emergency bailout if postmaster has died. This is to avoid the
173  * necessity for manual cleanup of all postmaster children. Do this less
174  * frequently on systems for which we don't have signals to make that
175  * cheap.
176  */
177  if (IsUnderPostmaster &&
179  postmaster_poll_count++ % POSTMASTER_POLL_RATE_LIMIT == 0 &&
180 #endif
182  exit(1);
183 
184  /* Process barrier events */
187 }
188 
189 
190 /* --------------------------------
191  * signal handler routines
192  * --------------------------------
193  */
194 static void
196 {
197  /* Shutdown the recovery environment */
200 }
201 
202 
203 /* ----------------------------------
204  * Startup Process main entry point
205  * ----------------------------------
206  */
207 void
209 {
210  /* Arrange to clean up at startup process exit */
212 
213  /*
214  * Properly accept or ignore signals the postmaster might send us.
215  */
216  pqsignal(SIGHUP, StartupProcSigHupHandler); /* reload config file */
217  pqsignal(SIGINT, SIG_IGN); /* ignore query cancel */
218  pqsignal(SIGTERM, StartupProcShutdownHandler); /* request shutdown */
219  /* SIGQUIT handler was already set up by InitPostmasterChild */
220  InitializeTimeouts(); /* establishes SIGALRM handler */
224 
225  /*
226  * Reset some signals that are accepted by postmaster but not here
227  */
229 
230  /*
231  * Register timeouts needed for standby mode
232  */
236 
237  /*
238  * Unblock signals (they were blocked when the postmaster forked us)
239  */
241 
242  /*
243  * Do what we came for.
244  */
245  StartupXLOG();
246 
247  /*
248  * Exit normally. Exit code 0 tells postmaster that we completed recovery
249  * successfully.
250  */
251  proc_exit(0);
252 }
253 
254 void
256 {
257  /*
258  * Set in_restore_command to tell the signal handler that we should exit
259  * right away on SIGTERM. We know that we're at a safe point to do that.
260  * Check if we had already received the signal, so that we don't miss a
261  * shutdown request received just before this.
262  */
263  in_restore_command = true;
264  if (shutdown_requested)
265  proc_exit(1);
266 }
267 
268 void
270 {
271  in_restore_command = false;
272 }
273 
274 bool
276 {
277  return promote_signaled;
278 }
279 
280 void
282 {
283  promote_signaled = false;
284 }
void InitializeTimeouts(void)
Definition: timeout.c:435
void StandbyTimeoutHandler(void)
Definition: standby.c:904
void ProcessConfigFile(GucContext context)
char * PrimarySlotName
Definition: xlog.c:279
#define SIGUSR1
Definition: win32_port.h:171
#define SIGCHLD
Definition: win32_port.h:169
bool IsPromoteSignaled(void)
Definition: startup.c:275
char * pstrdup(const char *in)
Definition: mcxt.c:1299
void StartupProcessMain(void)
Definition: startup.c:208
void ProcessProcSignalBarrier(void)
Definition: procsignal.c:453
static volatile sig_atomic_t shutdown_requested
Definition: startup.c:53
void proc_exit(int code)
Definition: ipc.c:104
#define SIGPIPE
Definition: win32_port.h:164
#define SIGUSR2
Definition: win32_port.h:172
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
static volatile sig_atomic_t got_SIGHUP
Definition: startup.c:52
void pfree(void *pointer)
Definition: mcxt.c:1169
void PostRestoreCommand(void)
Definition: startup.c:269
char * PrimaryConnInfo
Definition: xlog.c:278
#define POSTMASTER_POLL_RATE_LIMIT
Definition: startup.c:46
void WakeupRecovery(void)
Definition: xlog.c:12972
static volatile sig_atomic_t in_restore_command
Definition: startup.c:60
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:361
static void StartupProcSigHupHandler(SIGNAL_ARGS)
Definition: startup.c:89
HotStandbyState standbyState
Definition: xlogutils.c:55
bool IsUnderPostmaster
Definition: globals.c:112
#define SIGHUP
Definition: win32_port.h:159
#define PostmasterIsAlive()
Definition: pmsignal.h:102
void StandbyLockTimeoutHandler(void)
Definition: standby.c:916
void StandbyDeadLockHandler(void)
Definition: standby.c:893
unsigned int uint32
Definition: c.h:441
static void StartupRereadConfig(void)
Definition: startup.c:121
sigset_t UnBlockSig
Definition: pqsignal.c:22
void StartupXLOG(void)
Definition: xlog.c:6495
Definition: guc.h:72
#define SIG_IGN
Definition: win32_port.h:156
bool wal_receiver_create_temp_slot
Definition: xlog.c:281
static volatile sig_atomic_t promote_signaled
Definition: startup.c:54
uintptr_t Datum
Definition: postgres.h:411
pqsigfunc pqsignal(int signum, pqsigfunc handler)
Definition: signal.c:170
void ResetPromoteSignaled(void)
Definition: startup.c:281
TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler)
Definition: timeout.c:469
#define SIG_DFL
Definition: win32_port.h:154
static void StartupProcTriggerHandler(SIGNAL_ARGS)
Definition: startup.c:77
#define SIGNAL_ARGS
Definition: c.h:1333
static void StartupProcShutdownHandler(SIGNAL_ARGS)
Definition: startup.c:101
volatile sig_atomic_t ProcSignalBarrierPending
Definition: globals.c:37
void StartupRequestWalReceiverRestart(void)
Definition: xlog.c:12806
void PreRestoreCommand(void)
Definition: startup.c:255
void HandleStartupProcInterrupts(void)
Definition: startup.c:150
void * arg
void ShutdownRecoveryTransactionEnvironment(void)
Definition: standby.c:138
void procsignal_sigusr1_handler(SIGNAL_ARGS)
Definition: procsignal.c:642
static void StartupProcExit(int code, Datum arg)
Definition: startup.c:195