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

Commit4d4005c

Browse files
committed
Split up process latch initialization for more-fail-soft behavior.
In the previous coding, new backend processes would attempt to create theirself-pipe during the OwnLatch call in InitProcess. However, pipe creationcould fail if the kernel is short of resources; and the system does notrecover gracefully from a FATAL error right there, since we have armed thedead-man switch for this process and not yet set up the on_shmem_exitcallback that would disarm it. The postmaster then forces an unnecessarydatabase-wide crash and restart, as reported by Sean Chittenden.There are various ways we could rearrange the code to fix this, but thesimplest and sanest seems to be to split out creation of the self-pipe intoa new function InitializeLatchSupport, which must be called from a placewhere failure is allowed. For most processes that gets called inInitProcess or InitAuxiliaryProcess, but processes that don't call eitherbut still use latches need their own calls.Back-patch to 9.1, which has only a part of the latch logic that 9.2 andHEAD have, but nonetheless includes this bug.
1 parent0fbd443 commit4d4005c

File tree

7 files changed

+67
-36
lines changed

7 files changed

+67
-36
lines changed

‎src/backend/port/unix_latch.c

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,50 @@ static volatile sig_atomic_t waiting = false;
6060
staticintselfpipe_readfd=-1;
6161
staticintselfpipe_writefd=-1;
6262

63-
/* private function prototypes */
64-
staticvoidinitSelfPipe(void);
65-
staticvoiddrainSelfPipe(void);
63+
/* Private function prototypes */
6664
staticvoidsendSelfPipeByte(void);
65+
staticvoiddrainSelfPipe(void);
66+
67+
68+
/*
69+
* Initialize the process-local latch infrastructure.
70+
*
71+
* This must be called once during startup of any process that can wait on
72+
* latches, before it issues any InitLatch() or OwnLatch() calls.
73+
*/
74+
void
75+
InitializeLatchSupport(void)
76+
{
77+
intpipefd[2];
78+
79+
Assert(selfpipe_readfd==-1);
80+
81+
/*
82+
* Set up the self-pipe that allows a signal handler to wake up the
83+
* select() in WaitLatch. Make the write-end non-blocking, so that
84+
* SetLatch won't block if the event has already been set many times
85+
* filling the kernel buffer. Make the read-end non-blocking too, so that
86+
* we can easily clear the pipe by reading until EAGAIN or EWOULDBLOCK.
87+
*/
88+
if (pipe(pipefd)<0)
89+
elog(FATAL,"pipe() failed: %m");
90+
if (fcntl(pipefd[0],F_SETFL,O_NONBLOCK)<0)
91+
elog(FATAL,"fcntl() failed on read-end of self-pipe: %m");
92+
if (fcntl(pipefd[1],F_SETFL,O_NONBLOCK)<0)
93+
elog(FATAL,"fcntl() failed on write-end of self-pipe: %m");
6794

95+
selfpipe_readfd=pipefd[0];
96+
selfpipe_writefd=pipefd[1];
97+
}
6898

6999
/*
70100
* Initialize a backend-local latch.
71101
*/
72102
void
73103
InitLatch(volatileLatch*latch)
74104
{
75-
/* Initialize the self-pipe if this is our first latch in the process */
76-
if (selfpipe_readfd==-1)
77-
initSelfPipe();
105+
/* Assert InitializeLatchSupport has been called in this process */
106+
Assert(selfpipe_readfd >=0);
78107

79108
latch->is_set= false;
80109
latch->owner_pid=MyProcPid;
@@ -116,11 +145,10 @@ InitSharedLatch(volatile Latch *latch)
116145
void
117146
OwnLatch(volatileLatch*latch)
118147
{
119-
Assert(latch->is_shared);
148+
/* Assert InitializeLatchSupport has been called in this process */
149+
Assert(selfpipe_readfd >=0);
120150

121-
/* Initialize the self-pipe if this is our first latch in this process */
122-
if (selfpipe_readfd==-1)
123-
initSelfPipe();
151+
Assert(latch->is_shared);
124152

125153
/* sanity check */
126154
if (latch->owner_pid!=0)
@@ -511,30 +539,6 @@ latch_sigusr1_handler(void)
511539
sendSelfPipeByte();
512540
}
513541

514-
/* initialize the self-pipe */
515-
staticvoid
516-
initSelfPipe(void)
517-
{
518-
intpipefd[2];
519-
520-
/*
521-
* Set up the self-pipe that allows a signal handler to wake up the
522-
* select() in WaitLatch. Make the write-end non-blocking, so that
523-
* SetLatch won't block if the event has already been set many times
524-
* filling the kernel buffer. Make the read-end non-blocking too, so that
525-
* we can easily clear the pipe by reading until EAGAIN or EWOULDBLOCK.
526-
*/
527-
if (pipe(pipefd)<0)
528-
elog(FATAL,"pipe() failed: %m");
529-
if (fcntl(pipefd[0],F_SETFL,O_NONBLOCK)<0)
530-
elog(FATAL,"fcntl() failed on read-end of self-pipe: %m");
531-
if (fcntl(pipefd[1],F_SETFL,O_NONBLOCK)<0)
532-
elog(FATAL,"fcntl() failed on write-end of self-pipe: %m");
533-
534-
selfpipe_readfd=pipefd[0];
535-
selfpipe_writefd=pipefd[1];
536-
}
537-
538542
/* Send one byte to the self-pipe, to wake up WaitLatch */
539543
staticvoid
540544
sendSelfPipeByte(void)

‎src/backend/port/win32_latch.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
#include"storage/shmem.h"
3131

3232

33+
void
34+
InitializeLatchSupport(void)
35+
{
36+
/* currently, nothing to do here for Windows */
37+
}
38+
3339
void
3440
InitLatch(volatileLatch*latch)
3541
{

‎src/backend/postmaster/pgarch.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,6 @@ PgArchiverMain(int argc, char *argv[])
234234

235235
MyProcPid=getpid();/* reset MyProcPid */
236236

237-
InitLatch(&mainloop_latch);/* initialize latch used in main loop */
238-
239237
MyStartTime=time(NULL);/* record Start Time for logging */
240238

241239
/*
@@ -247,6 +245,10 @@ PgArchiverMain(int argc, char *argv[])
247245
elog(FATAL,"setsid() failed: %m");
248246
#endif
249247

248+
InitializeLatchSupport();/* needed for latch waits */
249+
250+
InitLatch(&mainloop_latch);/* initialize latch used in main loop */
251+
250252
/*
251253
* Ignore all signals usually bound to some action in the postmaster,
252254
* except for SIGHUP, SIGTERM, SIGUSR1, SIGUSR2, and SIGQUIT.

‎src/backend/postmaster/pgstat.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3021,6 +3021,8 @@ PgstatCollectorMain(int argc, char *argv[])
30213021
elog(FATAL,"setsid() failed: %m");
30223022
#endif
30233023

3024+
InitializeLatchSupport();/* needed for latch waits */
3025+
30243026
/* Initialize private latch for use by signal handlers */
30253027
InitLatch(&pgStatLatch);
30263028

‎src/backend/postmaster/syslogger.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ SysLoggerMain(int argc, char *argv[])
250250
elog(FATAL,"setsid() failed: %m");
251251
#endif
252252

253+
InitializeLatchSupport();/* needed for latch waits */
254+
253255
/* Initialize private latch for use by signal handlers */
254256
InitLatch(&sysLoggerLatch);
255257

‎src/backend/storage/lmgr/proc.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,13 @@ InitProcess(void)
291291
if (MyProc!=NULL)
292292
elog(ERROR,"you already exist");
293293

294+
/*
295+
* Initialize process-local latch support. This could fail if the kernel
296+
* is low on resources, and if so we want to exit cleanly before acquiring
297+
* any shared-memory resources.
298+
*/
299+
InitializeLatchSupport();
300+
294301
/*
295302
* Try to get a proc struct from the free list. If this fails, we must be
296303
* out of PGPROC structures (not to mention semaphores).
@@ -464,6 +471,13 @@ InitAuxiliaryProcess(void)
464471
if (MyProc!=NULL)
465472
elog(ERROR,"you already exist");
466473

474+
/*
475+
* Initialize process-local latch support. This could fail if the kernel
476+
* is low on resources, and if so we want to exit cleanly before acquiring
477+
* any shared-memory resources.
478+
*/
479+
InitializeLatchSupport();
480+
467481
/*
468482
* We use the ProcStructLock to protect assignment and releasing of
469483
* AuxiliaryProcs entries.

‎src/include/storage/latch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ typedef struct
111111
/*
112112
* prototypes for functions in latch.c
113113
*/
114+
externvoidInitializeLatchSupport(void);
114115
externvoidInitLatch(volatileLatch*latch);
115116
externvoidInitSharedLatch(volatileLatch*latch);
116117
externvoidOwnLatch(volatileLatch*latch);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp