]> granicus.if.org Git - postgresql/commitdiff
Improve tests for postmaster death in auxiliary processes.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 10 May 2012 04:54:32 +0000 (00:54 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 10 May 2012 04:54:56 +0000 (00:54 -0400)
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.

src/backend/postmaster/bgwriter.c
src/backend/postmaster/checkpointer.c
src/backend/postmaster/pgstat.c
src/backend/postmaster/walwriter.c

index f72672ef3be8caff1e80940fe6a9a2d14dc5c1f3..abb665ee50d684919b94a86a3827d84f87f64590 100644 (file)
@@ -323,9 +323,11 @@ BackgroundWriterMain(void)
 
                /*
                 * 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);
 
                prev_hibernate = can_hibernate;
index fa3435710d7ca0bab158cc5ab1cd52a95142b2e6..7f8ba95c44d30c9a9599ace7ec321b5f5cb72293 100644 (file)
@@ -374,17 +374,11 @@ CheckpointerMain(void)
                pg_time_t       now;
                int                     elapsed_secs;
                int                     cur_timeout;
+               int                     rc;
 
                /* Clear any already-pending wakeups */
                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.
                 */
@@ -581,9 +575,18 @@ CheckpointerMain(void)
                        cur_timeout = Min(cur_timeout, XLogArchiveTimeout - elapsed_secs);
                }
 
-               (void) WaitLatch(&MyProc->procLatch,
-                                                WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                cur_timeout * 1000L /* convert to ms */);
+               rc = WaitLatch(&MyProc->procLatch,
+                                          WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+                                          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);
        }
 }
 
index 191813a078ff829f719547956c9bc63b02c08013..15002dcd9d1b66c9aa53b36c257f73ad2965574a 100644 (file)
@@ -3225,8 +3225,13 @@ PgstatCollectorMain(int argc, char *argv[])
                                                           pgStatSock,
                                                           -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;
        }                                                       /* end of outer loop */
 
index 733d01fd5b3249d13ee637d8e2d8ec68a4555faa..886ad4f9267e420d742b54780a4c1db06c533f9c 100644 (file)
@@ -246,6 +246,7 @@ WalWriterMain(void)
        for (;;)
        {
                long    cur_timeout;
+               int             rc;
 
                /*
                 * Advertise whether we might hibernate in this cycle.  We do this
@@ -265,13 +266,6 @@ WalWriterMain(void)
                /* Clear any already-pending wakeups */
                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.
                 */
@@ -305,9 +299,18 @@ WalWriterMain(void)
                else
                        cur_timeout = WalWriterDelay * HIBERNATE_FACTOR;
 
-               (void) WaitLatch(&MyProc->procLatch,
-                                                WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                cur_timeout);
+               rc = WaitLatch(&MyProc->procLatch,
+                                          WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
+                                          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);
        }
 }