Hi,

15 19:48:23 +0900 (Tokyo Standard Time), Kyotaro HORIGUCHI 
<horiguchi.kyot...@lab.ntt.co.jp> wrote in 
<20150210.194823.219136034.horiguchi.kyot...@lab.ntt.co.jp>
> Considering pg_basebackup/receivexlog, the loop in receivelog.c
> does not maintain the time value within it, so I think we are
> forced to use feGetCurrentTimeStamp if not using SIGALRM. The wal
> reading function simply gets the data from the buffer in memory
> for most calls so the gettimeofday for each iteration could slow
> the process significantly. SIGALRM seems to be valuable for the
> case.

As a very fancy and ugly sample, the attached patch does this,
although, I'm a bit at a loss how to make this signal things to
be more sober..

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
>From 2dc0123c22902069986d25552902899b5ac537b1 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horiguchi.kyot...@lab.ntt.co.jp>
Date: Tue, 10 Feb 2015 21:30:12 +0900
Subject: [PATCH] receivelog.c sigalrm

---
 src/bin/pg_basebackup/receivelog.c | 44 ++++++++++++++++++++++++++++++++++----
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c
index 8caedff..d2e4c1a 100644
--- a/src/bin/pg_basebackup/receivelog.c
+++ b/src/bin/pg_basebackup/receivelog.c
@@ -16,6 +16,8 @@
 
 #include <sys/stat.h>
 #include <unistd.h>
+#include <signal.h>
+#include <sys/time.h>
 
 /* local includes */
 #include "receivelog.h"
@@ -801,6 +803,13 @@ ReadEndOfStreamingResult(PGresult *res, XLogRecPtr *startpos, uint32 *timeline)
 	return true;
 }
 
+static bool sigalrm_fired = false;
+static void
+SigAlrmHandler(int s)
+{
+	sigalrm_fired = true;
+}
+
 /*
  * The main loop of ReceiveXlogStream. Handles the COPY stream after
  * initiating streaming with the START_STREAMING command.
@@ -818,6 +827,10 @@ HandleCopyStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
 	char	   *copybuf = NULL;
 	int64		last_status = -1;
 	XLogRecPtr	blockpos = startpos;
+	sighandler_t oldhandler;
+
+	oldhandler = pqsignal(SIGALRM, SigAlrmHandler);
+	Assert(oldhandler == SIG_DFL);
 
 	still_sending = true;
 
@@ -879,6 +892,22 @@ HandleCopyStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
 		sleeptime = CalculateCopyStreamSleeptime(now, standby_message_timeout,
 												 last_status);
 
+		{
+			struct itimerval itv;
+			long secs;
+			int  usecs;
+			int err;
+
+			MemSet(&itv, 0, sizeof(itv));
+			itv.it_value.tv_sec = standby_message_timeout / 1000;
+			itv.it_value.tv_usec = (standby_message_timeout % 1000) * 1000;
+			sigalrm_fired = false;
+			if (setitimer(ITIMER_REAL, &itv, NULL) != 0)
+			{
+				fprintf(stderr, "could not set timer: %m");
+				goto error;
+			}
+		}
 		r = CopyStreamReceive(conn, sleeptime, &copybuf);
 		while (r != 0)
 		{
@@ -924,15 +953,22 @@ HandleCopyStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline,
 				goto error;
 			}
 
-			/*
-			 * Process the received data, and any subsequent data we
-			 * can read without blocking.
-			 */
+			if (sigalrm_fired)
+				break;
+
 			r = CopyStreamReceive(conn, 0, &copybuf);
 		}
+		if (!sigalrm_fired)
+		{
+			struct itimerval itv;
+			MemSet(&itv, 0, sizeof(itv));
+			setitimer(ITIMER_REAL, &itv, NULL);
+		}
 	}
 
+
 error:
+	pqsignal(SIGALRM, SIG_IGN);
 	if (copybuf != NULL)
 		PQfreemem(copybuf);
 	return NULL;
-- 
2.1.0.GIT

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