From 925adeed0bc7ae6be0b6e40d6c6879cb3fe6b9c6 Mon Sep 17 00:00:00 2001
From: Amit Kapila <akapila@postgresql.org>
Date: Fri, 28 Jun 2024 10:17:53 +0530
Subject: [PATCH v3] pg_createsubscriber: Warn the two-phase is disabled for
 logical replication

For now, pg_createsubscriber sets up with the two-phase commit disabled because
the setting is a default behaivor of logical replication. This commit adds the
description in the doc, and output warning when max_prepared_tranasctions > 0
on the publisher node.
---
 doc/src/sgml/ref/pg_createsubscriber.sgml   |  9 +++++++++
 src/bin/pg_basebackup/pg_createsubscriber.c | 20 +++++++++++++++++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/ref/pg_createsubscriber.sgml b/doc/src/sgml/ref/pg_createsubscriber.sgml
index 2ee6eee9e3..12f48180c7 100644
--- a/doc/src/sgml/ref/pg_createsubscriber.sgml
+++ b/doc/src/sgml/ref/pg_createsubscriber.sgml
@@ -353,6 +353,15 @@ PostgreSQL documentation
     <application>pg_createsubscriber</application>.
    </para>
 
+   <para>
+    <application>pg_createsubscriber</application> sets up logical replication
+    with the two-phase commit disabled.  This means the prepared transactions
+    will be replicated at the commit prepared time. Once the setup is complete,
+    users can manually drop and re-create the subscriptions with two-phase
+    <link linkend="sql-createsubscription-params-with-two-phase"><literal>two_phase</literal></link>
+    enabled.
+   </para>
+
    <para>
     <application>pg_createsubscriber</application> changes the system
     identifier using <application>pg_resetwal</application>.  It would avoid
diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c
index 1138c20e56..798121af31 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -815,6 +815,7 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 	int			cur_repslots;
 	int			max_walsenders;
 	int			cur_walsenders;
+	int			max_prepared_transactions;
 
 	pg_log_info("checking settings on publisher");
 
@@ -855,9 +856,12 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 				 "WHERE name = 'max_wal_senders'), "
 				 "cur_mws AS "
 				 "(SELECT count(*) AS cmws FROM pg_catalog.pg_stat_activity "
-				 "WHERE backend_type = 'walsender') "
-				 "SELECT wallevel, tmrs, cmrs, tmws, cmws "
-				 "FROM wl, total_mrs, cur_mrs, total_mws, cur_mws");
+				 "WHERE backend_type = 'walsender'), "
+				 "cur_mpt AS "
+				 "(SELECT setting AS mpt FROM pg_catalog.pg_settings "
+				 "WHERE name = 'max_prepared_transactions') "
+				 "SELECT wallevel, tmrs, cmrs, tmws, cmws, mpt "
+				 "FROM wl, total_mrs, cur_mrs, total_mws, cur_mws, cur_mpt");
 
 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
 	{
@@ -871,6 +875,7 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 	cur_repslots = atoi(PQgetvalue(res, 0, 2));
 	max_walsenders = atoi(PQgetvalue(res, 0, 3));
 	cur_walsenders = atoi(PQgetvalue(res, 0, 4));
+	max_prepared_transactions = atoi(PQgetvalue(res, 0, 5));
 
 	PQclear(res);
 
@@ -879,6 +884,8 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 	pg_log_debug("publisher: current replication slots: %d", cur_repslots);
 	pg_log_debug("publisher: max_wal_senders: %d", max_walsenders);
 	pg_log_debug("publisher: current wal senders: %d", cur_walsenders);
+	pg_log_debug("publisher: max_prepared_transactions: %d",
+				 max_prepared_transactions);
 
 	disconnect_database(conn, false);
 
@@ -906,6 +913,13 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
 		failed = true;
 	}
 
+	if (max_prepared_transactions != 0)
+	{
+		pg_log_warning("two_phase will not be enabled for slots");
+		pg_log_warning_detail("Subscriptions will be created with the two_phase disabled.  "
+							  "Transactions will be replicated at at COMMIT PREPARED.");
+	}
+
 	pg_free(wal_level);
 
 	if (failed)
-- 
2.28.0.windows.1

