From 602315443dab0603bb4316eefc523485a0dc8fee Mon Sep 17 00:00:00 2001
From: Khanna <Shubham.Khanna@fujitsu.com>
Date: Tue, 24 Dec 2024 12:27:27 +0530
Subject: [PATCH v1] Validate-max_slot_wal_keep_size-in-pg_createsubscriber

This patch introduces validation for the 'max_slot_wal_keep_size' GUC in the
'pg_createsubscriber' utility. The utility now checks that the publisher's
'max_slot_wal_keep_size' is set to '-1' during subscription creation.
This ensures proper functioning of logical replication slots.

This patch updates 'pg_createsubscriber' to fetch and validate the
'max_slot_wal_keep_size' setting from the publisher.
The test case is added to validate correct warning reporting when
'max_slot_wal_keep_size' is misconfigured.

These changes ensures that logical replication does not fail due to improper
configuration of 'max_slot_wal_keep_size' on the publisher.
---
 src/bin/pg_basebackup/pg_createsubscriber.c      | 15 ++++++++++++++-
 .../pg_basebackup/t/040_pg_createsubscriber.pl   | 16 ++++++++++++++--
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c
index e96370a9ec..1fa37d80fe 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -849,6 +849,7 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 	int			max_walsenders;
 	int			cur_walsenders;
 	int			max_prepared_transactions;
+	int			max_slot_wal_keep_size;
 
 	pg_log_info("checking settings on publisher");
 
@@ -880,7 +881,8 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 				 " (SELECT count(*) FROM pg_catalog.pg_replication_slots),"
 				 " pg_catalog.current_setting('max_wal_senders'),"
 				 " (SELECT count(*) FROM pg_catalog.pg_stat_activity WHERE backend_type = 'walsender'),"
-				 " pg_catalog.current_setting('max_prepared_transactions')");
+				 " pg_catalog.current_setting('max_prepared_transactions'),"
+				 " pg_catalog.current_setting('max_slot_wal_keep_size')");
 
 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
 	{
@@ -895,6 +897,7 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 	max_walsenders = atoi(PQgetvalue(res, 0, 3));
 	cur_walsenders = atoi(PQgetvalue(res, 0, 4));
 	max_prepared_transactions = atoi(PQgetvalue(res, 0, 5));
+	max_slot_wal_keep_size = atoi(PQgetvalue(res, 0, 6));
 
 	PQclear(res);
 
@@ -905,6 +908,8 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 	pg_log_debug("publisher: current wal senders: %d", cur_walsenders);
 	pg_log_debug("publisher: max_prepared_transactions: %d",
 				 max_prepared_transactions);
+	pg_log_debug("publisher: max_slot_wal_keep_size: %d",
+				 max_slot_wal_keep_size);
 
 	disconnect_database(conn, false);
 
@@ -939,6 +944,14 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 							  "Prepared transactions will be replicated at COMMIT PREPARED.");
 	}
 
+	/* Validate max_slot_wal_keep_size */
+	if (max_slot_wal_keep_size != -1)
+	{
+		pg_log_warning("publisher requires 'max_slot_wal_keep_size = -1', but only %d remain",
+					   max_slot_wal_keep_size);
+		pg_log_warning_detail("Change the 'max_slot_wal_keep_size' configuration on the publisher to -1.");
+	}
+
 	pg_free(wal_level);
 
 	if (failed)
diff --git a/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl b/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl
index 0a900edb65..569065a579 100644
--- a/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl
+++ b/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl
@@ -318,8 +318,13 @@ $node_p->safe_psql($db1,
 $node_p->wait_for_replay_catchup($node_s);
 $node_s->stop;
 
+# Configure 'max_slot_wal_keep_size = 1' on the publisher and verify the
+# warning message
+$node_p->append_conf('postgresql.conf', 'max_slot_wal_keep_size = 1');
+$node_p->restart;
+
 # dry run mode on node S
-command_ok(
+command_checks_all(
 	[
 		'pg_createsubscriber', '--verbose',
 		'--recovery-timeout', "$PostgreSQL::Test::Utils::timeout_default",
@@ -335,7 +340,14 @@ command_ok(
 		$db1, '--database',
 		$db2
 	],
-	'run pg_createsubscriber --dry-run on node S');
+	0,
+	[qr/./],
+	[
+		qr/pg_createsubscriber: warning: publisher requires 'max_slot_wal_keep_size = -1'/,
+		qr/Change the 'max_slot_wal_keep_size' configuration on the publisher to -1./,
+	],
+	'Validate warning for misconfigured max_slot_wal_keep_size on the publisher'
+);
 
 # Check if node S is still a standby
 $node_s->start;
-- 
2.34.1

