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

Commite81e8f9

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 parent8b728e5 commite81e8f9

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)
@@ -514,30 +542,6 @@ latch_sigusr1_handler(void)
514542
sendSelfPipeByte();
515543
}
516544

517-
/* initialize the self-pipe */
518-
staticvoid
519-
initSelfPipe(void)
520-
{
521-
intpipefd[2];
522-
523-
/*
524-
* Set up the self-pipe that allows a signal handler to wake up the
525-
* select() in WaitLatch. Make the write-end non-blocking, so that
526-
* SetLatch won't block if the event has already been set many times
527-
* filling the kernel buffer. Make the read-end non-blocking too, so that
528-
* we can easily clear the pipe by reading until EAGAIN or EWOULDBLOCK.
529-
*/
530-
if (pipe(pipefd)<0)
531-
elog(FATAL,"pipe() failed: %m");
532-
if (fcntl(pipefd[0],F_SETFL,O_NONBLOCK)<0)
533-
elog(FATAL,"fcntl() failed on read-end of self-pipe: %m");
534-
if (fcntl(pipefd[1],F_SETFL,O_NONBLOCK)<0)
535-
elog(FATAL,"fcntl() failed on write-end of self-pipe: %m");
536-
537-
selfpipe_readfd=pipefd[0];
538-
selfpipe_writefd=pipefd[1];
539-
}
540-
541545
/* Send one byte to the self-pipe, to wake up WaitLatch */
542546
staticvoid
543547
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
@@ -3022,6 +3022,8 @@ PgstatCollectorMain(int argc, char *argv[])
30223022
elog(FATAL,"setsid() failed: %m");
30233023
#endif
30243024

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

‎src/backend/postmaster/syslogger.c

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

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

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

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

282+
/*
283+
* Initialize process-local latch support. This could fail if the kernel
284+
* is low on resources, and if so we want to exit cleanly before acquiring
285+
* any shared-memory resources.
286+
*/
287+
InitializeLatchSupport();
288+
282289
/*
283290
* Try to get a proc struct from the free list. If this fails, we must be
284291
* out of PGPROC structures (not to mention semaphores).
@@ -451,6 +458,13 @@ InitAuxiliaryProcess(void)
451458
if (MyProc!=NULL)
452459
elog(ERROR,"you already exist");
453460

461+
/*
462+
* Initialize process-local latch support. This could fail if the kernel
463+
* is low on resources, and if so we want to exit cleanly before acquiring
464+
* any shared-memory resources.
465+
*/
466+
InitializeLatchSupport();
467+
454468
/*
455469
* We use the ProcStructLock to protect assignment and releasing of
456470
* 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