From bf08f2292ffca14fd133aa0901d1563b6ecd6894 Mon Sep 17 00:00:00 2001
From: Simon Riggs <simon@2ndQuadrant.com>
Date: Mon, 4 Apr 2016 07:18:05 +0100
Subject: [PATCH] Avoid archiving XLOG_RUNNING_XACTS on idle server

If archive_timeout > 0 we should avoid logging XLOG_RUNNING_XACTS if idle.

Bug 13685 reported by Laurence Rowe, investigated in detail by Michael Paquier,
though this is not his proposed fix.
20151016203031.3019.72930@wrigleys.postgresql.org

Simple non-invasive patch to allow later backpatch to 9.4 and 9.5
---
 src/backend/postmaster/bgwriter.c |  5 ++++-
 src/backend/storage/ipc/standby.c | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 00f03d8acbe..654e4f8bd57 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -330,8 +330,11 @@ BackgroundWriterMain(void)
 			if (now >= timeout &&
 				last_snapshot_lsn != GetXLogInsertRecPtr())
 			{
-				last_snapshot_lsn = LogStandbySnapshot();
+				XLogRecPtr log_standby_lsn = LogStandbySnapshot();
+
 				last_snapshot_ts = now;
+				if (!XLogRecPtrIsInvalid(log_standby_lsn))
+					last_snapshot_lsn = log_standby_lsn;
 			}
 		}
 
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 6a9bf842d39..8b9b438ca92 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -902,6 +902,7 @@ LogStandbySnapshot(void)
 	RunningTransactions running;
 	xl_standby_lock *locks;
 	int			nlocks;
+	static bool last_snapshot_overflowed = false;
 
 	Assert(XLogStandbyInfoActive());
 
@@ -932,8 +933,28 @@ LogStandbySnapshot(void)
 	 * only a shared lock.
 	 */
 	if (wal_level < WAL_LEVEL_LOGICAL)
+	{
 		LWLockRelease(ProcArrayLock);
 
+		/*
+		 * Don't bother to log anything if nothing is happening, if we are
+		 * using archive_timeout > 0 and we didn't overflow snapshot last time.
+		 *
+		 * This ensures that we don't issue an empty WAL record, which can
+		 * be annoying when used in conjunction with archive timeout.
+		 */
+		if (running->xcnt == 0 &&
+			nlocks == 0 &&
+			XLogArchiveTimeout > 0 &&
+			!last_snapshot_overflowed)
+		{
+			LWLockRelease(XidGenLock);
+			return InvalidXLogRecPtr;
+		}
+
+		last_snapshot_overflowed = running->subxid_overflow;
+	}
+
 	recptr = LogCurrentRunningXacts(running);
 
 	/* Release lock if we kept it longer ... */
-- 
GitLab