Improve tests for postmaster death in auxiliary processes.

In checkpointer and walwriter, avoid calling PostmasterIsAlive unless
WaitLatch has reported WL_POSTMASTER_DEATH.  This saves a kernel call per
iteration of the process's outer loop, which is not all that much, but a
cycle shaved is a cycle earned.  I had already removed the unconditional
PostmasterIsAlive calls in bgwriter and pgstat in previous patches, but
forgot that WL_POSTMASTER_DEATH is supposed to be treated as untrustworthy
(per comment in unix_latch.c); so adjust those two cases to match.

There are a few other places where the same idea might be applied, but only
after substantial code rearrangement, so I didn't bother.
This commit is contained in:
Tom Lane 2012-05-10 00:54:32 -04:00
parent e78cc624e8
commit fd71421b01
4 changed files with 37 additions and 24 deletions

View File

@ -323,9 +323,11 @@ BackgroundWriterMain(void)
/* /*
* Emergency bailout if postmaster has died. This is to avoid the * Emergency bailout if postmaster has died. This is to avoid the
* necessity for manual cleanup of all postmaster children. * necessity for manual cleanup of all postmaster children. Note
* that we mustn't trust the WL_POSTMASTER_DEATH result flag entirely;
* if it is set, recheck with PostmasterIsAlive before believing it.
*/ */
if (rc & WL_POSTMASTER_DEATH) if ((rc & WL_POSTMASTER_DEATH) && !PostmasterIsAlive())
exit(1); exit(1);
prev_hibernate = can_hibernate; prev_hibernate = can_hibernate;

View File

@ -374,17 +374,11 @@ CheckpointerMain(void)
pg_time_t now; pg_time_t now;
int elapsed_secs; int elapsed_secs;
int cur_timeout; int cur_timeout;
int rc;
/* Clear any already-pending wakeups */ /* Clear any already-pending wakeups */
ResetLatch(&MyProc->procLatch); ResetLatch(&MyProc->procLatch);
/*
* Emergency bailout if postmaster has died. This is to avoid the
* necessity for manual cleanup of all postmaster children.
*/
if (!PostmasterIsAlive())
exit(1);
/* /*
* Process any requests or signals received recently. * Process any requests or signals received recently.
*/ */
@ -581,9 +575,18 @@ CheckpointerMain(void)
cur_timeout = Min(cur_timeout, XLogArchiveTimeout - elapsed_secs); cur_timeout = Min(cur_timeout, XLogArchiveTimeout - elapsed_secs);
} }
(void) WaitLatch(&MyProc->procLatch, rc = WaitLatch(&MyProc->procLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
cur_timeout * 1000L /* convert to ms */); cur_timeout * 1000L /* convert to ms */);
/*
* Emergency bailout if postmaster has died. This is to avoid the
* necessity for manual cleanup of all postmaster children. Note
* that we mustn't trust the WL_POSTMASTER_DEATH result flag entirely;
* if it is set, recheck with PostmasterIsAlive before believing it.
*/
if ((rc & WL_POSTMASTER_DEATH) && !PostmasterIsAlive())
exit(1);
} }
} }

View File

@ -3225,8 +3225,13 @@ PgstatCollectorMain(int argc, char *argv[])
pgStatSock, pgStatSock,
-1L); -1L);
/* Check for postmaster death */ /*
if (wr & WL_POSTMASTER_DEATH) * Emergency bailout if postmaster has died. This is to avoid the
* necessity for manual cleanup of all postmaster children. Note
* that we mustn't trust the WL_POSTMASTER_DEATH result flag entirely;
* if it is set, recheck with PostmasterIsAlive before believing it.
*/
if ((wr & WL_POSTMASTER_DEATH) && !PostmasterIsAlive())
break; break;
} /* end of outer loop */ } /* end of outer loop */

View File

@ -246,6 +246,7 @@ WalWriterMain(void)
for (;;) for (;;)
{ {
long cur_timeout; long cur_timeout;
int rc;
/* /*
* Advertise whether we might hibernate in this cycle. We do this * Advertise whether we might hibernate in this cycle. We do this
@ -265,13 +266,6 @@ WalWriterMain(void)
/* Clear any already-pending wakeups */ /* Clear any already-pending wakeups */
ResetLatch(&MyProc->procLatch); ResetLatch(&MyProc->procLatch);
/*
* Emergency bailout if postmaster has died. This is to avoid the
* necessity for manual cleanup of all postmaster children.
*/
if (!PostmasterIsAlive())
exit(1);
/* /*
* Process any requests or signals received recently. * Process any requests or signals received recently.
*/ */
@ -305,9 +299,18 @@ WalWriterMain(void)
else else
cur_timeout = WalWriterDelay * HIBERNATE_FACTOR; cur_timeout = WalWriterDelay * HIBERNATE_FACTOR;
(void) WaitLatch(&MyProc->procLatch, rc = WaitLatch(&MyProc->procLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
cur_timeout); cur_timeout);
/*
* Emergency bailout if postmaster has died. This is to avoid the
* necessity for manual cleanup of all postmaster children. Note
* that we mustn't trust the WL_POSTMASTER_DEATH result flag entirely;
* if it is set, recheck with PostmasterIsAlive before believing it.
*/
if ((rc & WL_POSTMASTER_DEATH) && !PostmasterIsAlive())
exit(1);
} }
} }