From 0198d7fb73f1d19ba6ae6a004204a1737affe742 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Thu, 26 Jun 2025 00:32:38 +0300
Subject: [PATCH v1] Fix CheckPointReplicationSlots() with
 max_replication_slots == 0

ca307d5cec90 made CheckPointReplicationSlots() unconditionally call
ReplicationSlotsComputeRequiredLSN().  It causes an assertion trap when
max_replication_slots equals 0.  This commit makes
CheckPointReplicationSlots() call ReplicationSlotsComputeRequiredLSN() only
when at least one slot gets its last_saved_restart_lsn updated.  That avoids
an assert trap and also saves some cycles when no one slot has
last_saved_restart_lsn updated.

Based on ideas from Dilip Kumar <dilipbalaut@gmail.com> and
Hayato Kuroda <kuroda.hayato@fujitsu.com>.

Reported-by: Zhijie Hou <houzj.fnst@fujitsu.com>
Discussion: https://postgr.es/m/OS0PR01MB5716BB506AF934376FF3A8BB947BA%40OS0PR01MB5716.jpnprd01.prod.outlook.com
---
 src/backend/replication/slot.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index c11e588d632..30177388508 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -2079,6 +2079,7 @@ void
 CheckPointReplicationSlots(bool is_shutdown)
 {
 	int			i;
+	bool		last_saved_restart_lsn_updated = false;
 
 	elog(DEBUG1, "performing replication slot checkpoint");
 
@@ -2123,15 +2124,23 @@ CheckPointReplicationSlots(bool is_shutdown)
 			SpinLockRelease(&s->mutex);
 		}
 
+		/*
+		 * Track if we're going to update slot's last_saved_restart_lsn.
+		 * We need this to know if we need to recompute the required LSN.
+		 */
+		if (s->last_saved_restart_lsn != s->data.restart_lsn)
+			last_saved_restart_lsn_updated = true;
+
 		SaveSlotToPath(s, path, LOG);
 	}
 	LWLockRelease(ReplicationSlotAllocationLock);
 
 	/*
-	 * Recompute the required LSN as SaveSlotToPath() updated
-	 * last_saved_restart_lsn for slots.
+	 * Recompute the required LSN if SaveSlotToPath() updated
+	 * last_saved_restart_lsn for any slot.
 	 */
-	ReplicationSlotsComputeRequiredLSN();
+	if (last_saved_restart_lsn_updated)
+		ReplicationSlotsComputeRequiredLSN();
 }
 
 /*
-- 
2.39.5 (Apple Git-154)

