From 4909cb59df40a011b041ce97a68e4d73a54da6ee Mon Sep 17 00:00:00 2001
From: Tatsuo Ishii <ishii@postgresql.org>
Date: Sat, 14 Mar 2015 08:16:50 +0900
Subject: [PATCH] Fix integer overflow in debug message of walreceiver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The message tries to tell the replication apply delay which fails if
the first WAL record is not applied yet. Fix is, instead of telling
overflowed minus numeric, showing "N/A" which indicates that the delay
data is not yet available. Problem reported by me and patch by
Fabrízio de Royes Mello.

Back patched to 9.4, 9.3 and 9.2 stable branches (9.1 and 9.0 do not
have the debug message).
---
 src/backend/replication/walreceiver.c      | 21 ++++++++++++++++-----
 src/backend/replication/walreceiverfuncs.c | 12 ++++++++++--
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index 753316e8c37..ed3ef55ebe7 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -793,15 +793,26 @@ ProcessWalSndrMessage(XLogRecPtr walEnd, TimestampTz sendTime)
 	{
 		char	   *sendtime;
 		char	   *receipttime;
+		int			applyDelay;
 
 		/* Copy because timestamptz_to_str returns a static buffer */
 		sendtime = pstrdup(timestamptz_to_str(sendTime));
 		receipttime = pstrdup(timestamptz_to_str(lastMsgReceiptTime));
-		elog(DEBUG2, "sendtime %s receipttime %s replication apply delay %d ms transfer latency %d ms",
-			 sendtime,
-			 receipttime,
-			 GetReplicationApplyDelay(),
-			 GetReplicationTransferLatency());
+		applyDelay = GetReplicationApplyDelay();
+
+		/* apply delay is not available */
+		if (applyDelay == -1)
+			elog(DEBUG2, "sendtime %s receipttime %s replication apply delay (N/A) transfer latency %d ms",
+				 sendtime,
+				 receipttime,
+				 GetReplicationTransferLatency());
+		else
+			elog(DEBUG2, "sendtime %s receipttime %s replication apply delay %d ms transfer latency %d ms",
+				 sendtime,
+				 receipttime,
+				 applyDelay,
+				 GetReplicationTransferLatency());
+
 		pfree(sendtime);
 		pfree(receipttime);
 	}
diff --git a/src/backend/replication/walreceiverfuncs.c b/src/backend/replication/walreceiverfuncs.c
index e105f093d35..98706e3b9ba 100644
--- a/src/backend/replication/walreceiverfuncs.c
+++ b/src/backend/replication/walreceiverfuncs.c
@@ -241,7 +241,8 @@ GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart)
 }
 
 /*
- * Returns the replication apply delay in ms
+ * Returns the replication apply delay in ms or -1
+ * if the apply delay info is not available
  */
 int
 GetReplicationApplyDelay(void)
@@ -255,6 +256,8 @@ GetReplicationApplyDelay(void)
 	long		secs;
 	int			usecs;
 
+	TimestampTz	chunckReplayStartTime;
+
 	SpinLockAcquire(&walrcv->mutex);
 	receivePtr = walrcv->receivedUpto;
 	SpinLockRelease(&walrcv->mutex);
@@ -264,7 +267,12 @@ GetReplicationApplyDelay(void)
 	if (XLByteEQ(receivePtr, replayPtr))
 		return 0;
 
-	TimestampDifference(GetCurrentChunkReplayStartTime(),
+	chunckReplayStartTime = GetCurrentChunkReplayStartTime();
+
+	if (chunckReplayStartTime == 0)
+		return -1;
+
+	TimestampDifference(chunckReplayStartTime,
 						GetCurrentTimestamp(),
 						&secs, &usecs);
 
-- 
GitLab