postgres.git / summary / log / commit / refs
commit fd71421b0187de0e2bf76ff66b4a9433bd96c4a0
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu May 10 04:54:32 2012 +0000
First released in: 9.2.0
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.
src/backend/postmaster/bgwriter.c | 6 ++++--
src/backend/postmaster/checkpointer.c | 23 +++++++++++++----------
src/backend/postmaster/pgstat.c | 9 +++++++--
src/backend/postmaster/walwriter.c | 23 +++++++++++++----------
4 files changed, 37 insertions(+), 24 deletions(-)
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index f72672ef3be..abb665ee50d 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -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;
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index fa3435710d7..7f8ba95c44d 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -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);
}
}
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 191813a078f..15002dcd9d1 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -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 */
diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
index 733d01fd5b3..886ad4f9267 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -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);
}
}
[parent: e78cc624e877]