Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9f09529

Browse files
committed
Use signals for postmaster death on Linux.
Linux provides a way to ask for a signal when your parent process dies.Use that to make PostmasterIsAlive() very cheap.Based on a suggestion from Andres Freund.Author: Thomas Munro, Heikki LinnakangasReviewed-By: Michael PaquierDiscussion:https://postgr.es/m/7261eb39-0369-f2f4-1bb5-62f3b6083b5e%40iki.fiDiscussion:https://postgr.es/m/20180411002643.6buofht4ranhei7k%40alap3.anarazel.de
1 parent56a7147 commit9f09529

File tree

8 files changed

+159
-19
lines changed

8 files changed

+159
-19
lines changed

‎configure

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12494,7 +12494,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
1249412494
fi
1249512495

1249612496

12497-
for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
12497+
for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/prctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
1249812498
do :
1249912499
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
1250012500
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"

‎configure.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1260,7 +1260,7 @@ AC_SUBST(UUID_LIBS)
12601260

12611261
AC_HEADER_STDBOOL
12621262

1263-
AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
1263+
AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/prctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
12641264

12651265
# On BSD, test for net/if.h will fail unless sys/socket.h
12661266
# is included first.

‎src/backend/storage/ipc/latch.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
11121112
* WL_POSTMASTER_DEATH event would be painful. Re-checking doesn't
11131113
* cost much.
11141114
*/
1115-
if (!PostmasterIsAlive())
1115+
if (!PostmasterIsAliveInternal())
11161116
{
11171117
occurred_events->fd=PGINVALID_SOCKET;
11181118
occurred_events->events=WL_POSTMASTER_DEATH;
@@ -1230,7 +1230,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
12301230
* WL_POSTMASTER_DEATH event would be painful. Re-checking doesn't
12311231
* cost much.
12321232
*/
1233-
if (!PostmasterIsAlive())
1233+
if (!PostmasterIsAliveInternal())
12341234
{
12351235
occurred_events->fd=PGINVALID_SOCKET;
12361236
occurred_events->events=WL_POSTMASTER_DEATH;
@@ -1390,7 +1390,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
13901390
* even though there is no known reason to think that the event could
13911391
* be falsely set on Windows.
13921392
*/
1393-
if (!PostmasterIsAlive())
1393+
if (!PostmasterIsAliveInternal())
13941394
{
13951395
occurred_events->fd=PGINVALID_SOCKET;
13961396
occurred_events->events=WL_POSTMASTER_DEATH;

‎src/backend/storage/ipc/pmsignal.c

Lines changed: 112 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
#include<signal.h>
1818
#include<unistd.h>
1919

20+
#ifdefHAVE_SYS_PRCTL_H
21+
#include<sys/prctl.h>
22+
#endif
23+
2024
#include"miscadmin.h"
2125
#include"postmaster/postmaster.h"
2226
#include"replication/walsender.h"
@@ -71,6 +75,35 @@ struct PMSignalData
7175

7276
NON_EXEC_STATICvolatilePMSignalData*PMSignalState=NULL;
7377

78+
/*
79+
* Signal handler to be notified if postmaster dies.
80+
*/
81+
#ifdefUSE_POSTMASTER_DEATH_SIGNAL
82+
volatilesig_atomic_tpostmaster_possibly_dead= false;
83+
84+
staticvoid
85+
postmaster_death_handler(intsigno)
86+
{
87+
postmaster_possibly_dead= true;
88+
}
89+
90+
/*
91+
* The available signals depend on the OS. SIGUSR1 and SIGUSR2 are already
92+
* used for other things, so choose another one.
93+
*
94+
* Currently, we assume that we can always find a signal to use. That
95+
* seems like a reasonable assumption for all platforms that are modern
96+
* enough to have a parent-death signaling mechanism.
97+
*/
98+
#if defined(SIGINFO)
99+
#definePOSTMASTER_DEATH_SIGNAL SIGINFO
100+
#elif defined(SIGPWR)
101+
#definePOSTMASTER_DEATH_SIGNAL SIGPWR
102+
#else
103+
#error "cannot find a signal to use for postmaster death"
104+
#endif
105+
106+
#endif/* USE_POSTMASTER_DEATH_SIGNAL */
74107

75108
/*
76109
* PMSignalShmemSize
@@ -266,28 +299,94 @@ MarkPostmasterChildInactive(void)
266299

267300

268301
/*
269-
* PostmasterIsAlive - check whether postmaster process is still alive
302+
* PostmasterIsAliveInternal - check whether postmaster process is still alive
303+
*
304+
* This is the slow path of PostmasterIsAlive(), where the caller has already
305+
* checked 'postmaster_possibly_dead'. (On platforms that don't support
306+
* a signal for parent death, PostmasterIsAlive() is just an alias for this.)
270307
*/
271308
bool
272-
PostmasterIsAlive(void)
309+
PostmasterIsAliveInternal(void)
273310
{
274-
#ifndefWIN32
275-
charc;
276-
ssize_trc;
311+
#ifdefUSE_POSTMASTER_DEATH_SIGNAL
312+
/*
313+
* Reset the flag before checking, so that we don't miss a signal if
314+
* postmaster dies right after the check. If postmaster was indeed dead,
315+
* we'll re-arm it before returning to caller.
316+
*/
317+
postmaster_possibly_dead= false;
318+
#endif
277319

278-
rc=read(postmaster_alive_fds[POSTMASTER_FD_WATCH],&c,1);
279-
if (rc<0)
320+
#ifndefWIN32
280321
{
281-
if (errno==EAGAIN||errno==EWOULDBLOCK)
322+
charc;
323+
ssize_trc;
324+
325+
rc=read(postmaster_alive_fds[POSTMASTER_FD_WATCH],&c,1);
326+
327+
/*
328+
* In the usual case, the postmaster is still alive, and there is no
329+
* data in the pipe.
330+
*/
331+
if (rc<0&& (errno==EAGAIN||errno==EWOULDBLOCK))
282332
return true;
283333
else
284-
elog(FATAL,"read on postmaster death monitoring pipe failed: %m");
334+
{
335+
/*
336+
* Postmaster is dead, or something went wrong with the read()
337+
* call.
338+
*/
339+
340+
#ifdefUSE_POSTMASTER_DEATH_SIGNAL
341+
postmaster_possibly_dead= true;
342+
#endif
343+
344+
if (rc<0)
345+
elog(FATAL,"read on postmaster death monitoring pipe failed: %m");
346+
elseif (rc>0)
347+
elog(FATAL,"unexpected data in postmaster death monitoring pipe");
348+
349+
return false;
350+
}
285351
}
286-
elseif (rc>0)
287-
elog(FATAL,"unexpected data in postmaster death monitoring pipe");
288352

289-
return false;
290353
#else/* WIN32 */
291-
return (WaitForSingleObject(PostmasterHandle,0)==WAIT_TIMEOUT);
354+
if (WaitForSingleObject(PostmasterHandle,0)==WAIT_TIMEOUT)
355+
return true;
356+
else
357+
{
358+
#ifdefUSE_POSTMASTER_DEATH_SIGNAL
359+
postmaster_possibly_dead= true;
360+
#endif
361+
return false;
362+
}
292363
#endif/* WIN32 */
293364
}
365+
366+
/*
367+
* PostmasterDeathSignalInit - request signal on postmaster death if possible
368+
*/
369+
void
370+
PostmasterDeathSignalInit(void)
371+
{
372+
#ifdefUSE_POSTMASTER_DEATH_SIGNAL
373+
intsignum=POSTMASTER_DEATH_SIGNAL;
374+
375+
/* Register our signal handler. */
376+
pqsignal(signum,postmaster_death_handler);
377+
378+
/* Request a signal on parent exit. */
379+
#if defined(PR_SET_PDEATHSIG)
380+
if (prctl(PR_SET_PDEATHSIG,signum)<0)
381+
elog(ERROR,"could not request parent death signal: %m");
382+
#else
383+
#error "USE_POSTMASTER_DEATH_SIGNAL set, but there is no mechanism to request the signal"
384+
#endif
385+
386+
/*
387+
* Just in case the parent was gone already and we missed it, we'd better
388+
* check the slow way on the first call.
389+
*/
390+
postmaster_possibly_dead= true;
391+
#endif/* USE_POSTMASTER_DEATH_SIGNAL */
392+
}

‎src/backend/utils/init/miscinit.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include"storage/ipc.h"
4444
#include"storage/latch.h"
4545
#include"storage/pg_shmem.h"
46+
#include"storage/pmsignal.h"
4647
#include"storage/proc.h"
4748
#include"storage/procarray.h"
4849
#include"utils/builtins.h"
@@ -304,6 +305,9 @@ InitPostmasterChild(void)
304305
if (setsid()<0)
305306
elog(FATAL,"setsid() failed: %m");
306307
#endif
308+
309+
/* Request a signal if the postmaster dies, if possible. */
310+
PostmasterDeathSignalInit();
307311
}
308312

309313
/*

‎src/include/pg_config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,9 @@
600600
/* Define to 1 if you have the <sys/ipc.h> header file. */
601601
#undef HAVE_SYS_IPC_H
602602

603+
/* Define to 1 if you have the <sys/prctl.h> header file. */
604+
#undef HAVE_SYS_PRCTL_H
605+
603606
/* Define to 1 if you have the <sys/pstat.h> header file. */
604607
#undef HAVE_SYS_PSTAT_H
605608

‎src/include/pg_config.h.win32

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,9 @@
482482
/* Define to 1 if you have the <sys/ipc.h> header file. */
483483
/* #undef HAVE_SYS_IPC_H */
484484

485+
/* Define to 1 if you have the <sys/prctl.h> header file. */
486+
/* #undef HAVE_SYS_PRCTL_H */
487+
485488
/* Define to 1 if you have the <sys/pstat.h> header file. */
486489
/* #undef HAVE_SYS_PSTAT_H */
487490

‎src/include/storage/pmsignal.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
#ifndefPMSIGNAL_H
1515
#definePMSIGNAL_H
1616

17+
#ifdefHAVE_SYS_PRCTL_H
18+
#include"sys/prctl.h"
19+
#endif
20+
1721
/*
1822
* Reasons for signaling the postmaster. We can cope with simultaneous
1923
* signals for different reasons. If the same reason is signaled multiple
@@ -51,6 +55,33 @@ extern bool IsPostmasterChildWalSender(int slot);
5155
externvoidMarkPostmasterChildActive(void);
5256
externvoidMarkPostmasterChildInactive(void);
5357
externvoidMarkPostmasterChildWalSender(void);
54-
externboolPostmasterIsAlive(void);
58+
externboolPostmasterIsAliveInternal(void);
59+
externvoidPostmasterDeathSignalInit(void);
60+
61+
62+
/*
63+
* Do we have a way to ask for a signal on parent death?
64+
*
65+
* If we do, pmsignal.c will set up a signal handler, that sets a flag when
66+
* the parent dies. Checking the flag first makes PostmasterIsAlive() a lot
67+
* cheaper in usual case that the postmaster is alive.
68+
*/
69+
#if defined(HAVE_SYS_PRCTL_H)&& defined(PR_SET_PDEATHSIG)
70+
#defineUSE_POSTMASTER_DEATH_SIGNAL
71+
#endif
72+
73+
#ifdefUSE_POSTMASTER_DEATH_SIGNAL
74+
externvolatilesig_atomic_tpostmaster_possibly_dead;
75+
76+
staticinlinebool
77+
PostmasterIsAlive(void)
78+
{
79+
if (likely(!postmaster_possibly_dead))
80+
return true;
81+
returnPostmasterIsAliveInternal();
82+
}
83+
#else
84+
#definePostmasterIsAlive() PostmasterIsAliveInternal()
85+
#endif
5586

5687
#endif/* PMSIGNAL_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp