Attached is patch for the WAL writer that removes its tight polling
loop (which probably doesn't get hit often in practice, as we just
sleep if wal_writer_delay is under a second), and, at least
potentially, reduces power consumption when idle by using a latch.

I will break all remaining power consumption work down into
per-auxiliary process patches. I think that this is appropriate - if
we hit a snag on one of the processes, there is no need to have that
hold up everything.

I've commented that we handle all expected signals, and therefore we
shouldn't worry about having timeout invalidated by signals, just as
with the archiver. Previously, we didn't even worry about Postmaster
death within the tight polling loop, presumably because
wal_writer_delay is typically small enough to avoid that being a
problem. I thought that WL_POSTMASTER_DEATH might be superfluous here,
but then again there is a codepath specifically for the case where
wal_writer_delay exceeds one second, so it is included in this initial
version.

Comments?

-- 
Peter Geoghegan       http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training and Services
diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c
index 1411677..2027dd7 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -52,6 +52,7 @@
 #include "storage/bufmgr.h"
 #include "storage/fd.h"
 #include "storage/ipc.h"
+#include "storage/latch.h"
 #include "storage/lwlock.h"
 #include "storage/pmsignal.h"
 #include "storage/smgr.h"
@@ -79,7 +80,11 @@ static void WalShutdownHandler(SIGNAL_ARGS);
 
 
 /*
- * Main entry point for walwriter process
+ * Latch used by signal handlers to wake up the sleep in the main loop.
+ */
+static Latch mainloop_latch;
+
+/* Main entry point for walwriter process
  *
  * This is invoked from BootstrapMain, which has already created the basic
  * execution environment, but not enabled signals yet.
@@ -217,12 +222,16 @@ WalWriterMain(void)
 	PG_SETMASK(&UnBlockSig);
 
 	/*
+	 * Initialize latch used in loop below
+	 */
+	InitLatch(&mainloop_latch);
+
+	/*
 	 * Loop forever
 	 */
 	for (;;)
 	{
-		long		udelay;
-
+		ResetLatch(&mainloop_latch);
 		/*
 		 * Emergency bailout if postmaster has died.  This is to avoid the
 		 * necessity for manual cleanup of all postmaster children.
@@ -249,20 +258,8 @@ WalWriterMain(void)
 		 */
 		XLogBackgroundFlush();
 
-		/*
-		 * Delay until time to do something more, but fall out of delay
-		 * reasonably quickly if signaled.
-		 */
-		udelay = WalWriterDelay * 1000L;
-		while (udelay > 999999L)
-		{
-			if (got_SIGHUP || shutdown_requested)
-				break;
-			pg_usleep(1000000L);
-			udelay -= 1000000L;
-		}
-		if (!(got_SIGHUP || shutdown_requested))
-			pg_usleep(udelay);
+		/* We handle all expected signals, so WalWriterDelay timeout won't be invalidated */
+		WaitLatch(&mainloop_latch, WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, WalWriterDelay * 1000L);
 	}
 }
 
@@ -309,6 +306,8 @@ static void
 WalSigHupHandler(SIGNAL_ARGS)
 {
 	got_SIGHUP = true;
+	/* let the waiting loop iterate */
+	SetLatch(&mainloop_latch);
 }
 
 /* SIGTERM: set flag to exit normally */
@@ -316,4 +315,6 @@ static void
 WalShutdownHandler(SIGNAL_ARGS)
 {
 	shutdown_requested = true;
+	/* let the waiting loop iterate */
+	SetLatch(&mainloop_latch);
 }
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to