From 5e56bd0801962bd04fa2829d6f42579d85c47958 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Tue, 24 Oct 2023 16:01:11 -0700
Subject: [PATCH v1 2/2] Reduce rate of wakeups of walsender due to async
 commits

Author:
Reviewed-by:
Discussion: https://postgr.es/m/
Backpatch:
---
 src/backend/access/transam/xlog.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 6065fd63b8b..867ab3bd742 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -2437,14 +2437,23 @@ XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
 {
 	XLogRecPtr	WriteRqstPtr = asyncXactLSN;
 	bool		sleeping;
+	XLogRecPtr  prevAsyncXactLSN;
 
 	SpinLockAcquire(&XLogCtl->info_lck);
 	LogwrtResult = XLogCtl->LogwrtResult;
 	sleeping = XLogCtl->WalWriterSleeping;
+	prevAsyncXactLSN = XLogCtl->asyncXactLSN;
 	if (XLogCtl->asyncXactLSN < asyncXactLSN)
 		XLogCtl->asyncXactLSN = asyncXactLSN;
 	SpinLockRelease(&XLogCtl->info_lck);
 
+	/*
+	 * If somebody else already called this function with a more aggressive
+	 * LSN, they will have done what we needed (and perhaps more).
+	 */
+	if (asyncXactLSN <= prevAsyncXactLSN)
+		return;
+
 	/*
 	 * If the WALWriter is sleeping, we should kick it to make it come out of
 	 * low-power mode.  Otherwise, determine whether there's a full page of
@@ -2458,6 +2467,18 @@ XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
 		/* if we have already flushed that far, we're done */
 		if (WriteRqstPtr <= LogwrtResult.Flush)
 			return;
+
+		/*
+		 * There is no benefit in waking walwriter if we only have a small
+		 * amount of writes outstanding. We want to flush WAL at least once
+		 * per wal_writer_flush_after and not defer writing for more than
+		 * wal_writer_delay. As we wake walwriter below, if it's currently
+		 * hibernating, it's own loop will ensure that wal_writer_delay is
+		 * taken care of. This condition takes care of flushing if there is
+		 * more than wal_writer_flush_after unflushed data.
+		 */
+		if (WriteRqstPtr <= LogwrtResult.Flush + WalWriterFlushAfter * XLOG_BLCKSZ)
+			return;
 	}
 
 	/*
-- 
2.38.0

