On Wed, Feb 5, 2025, at 9:49 PM, Masahiko Sawada wrote:
> On Wed, Feb 5, 2025 at 4:39 PM Euler Taveira <eu...@eulerto.com> wrote:
> >
> > On Wed, Feb 5, 2025, at 1:56 AM, Amit Kapila wrote:
> >
> > On Wed, Feb 5, 2025 at 8:17 AM Euler Taveira <eu...@eulerto.com> wrote:
> > >
> > > Under reflection, an accurate name is 
> > > max_replication_origin_session_setup. A
> > > counter argument is that it is a long name (top-5 length).
> > >
> > > postgres=# select n, length(n) from (values('max_replication_origins'),
> > > ('max_tracked_replication_origins'),('max_replication_origin_states'),
> > > ('max_replication_origin_session_setup')) as gucs(n);
> > >                   n                   | length
> > > --------------------------------------+--------
> > > max_replication_origins              |     23
> > > max_tracked_replication_origins      |     31
> > > max_replication_origin_states        |     29
> > > max_replication_origin_session_setup |     36
> > > (4 rows)
> > >
> >
> > The other possibility is max_replication_origin_sessions.
> >
> >
> > Looks reasonable to me.
> >
> > Opinions?
> 
> +1

Here is another patch that only changes the GUC name to
max_replication_origin_sessions.


--
Euler Taveira
EDB   https://www.enterprisedb.com/
From 5500a6bd126534aa11477f923a2fafdb5fdc6b00 Mon Sep 17 00:00:00 2001
From: Euler Taveira <eu...@eulerto.com>
Date: Tue, 3 Sep 2024 12:10:20 -0300
Subject: [PATCH v4] Separate GUC for replication origins

The new GUC (max_replication_origin_sessions) defines the maximum number
of replication origins that can be configured simultaneously. The
max_replication_slots was used for this purpose but it is confusing
(when you are learning about logical replication) and introduces a
limitation (you cannot have a small number of replication slots and a
high number of subscriptions).

For backward compatibility, the default is -1, indicating that the value
of max_replication_slots is used instead.
---
 doc/src/sgml/config.sgml                      | 27 ++----
 doc/src/sgml/logical-replication.sgml         |  6 +-
 doc/src/sgml/ref/pg_createsubscriber.sgml     |  2 +-
 src/backend/replication/logical/launcher.c    |  6 +-
 src/backend/replication/logical/origin.c      | 92 ++++++++++++-------
 src/backend/utils/misc/guc_tables.c           | 12 +++
 src/backend/utils/misc/postgresql.conf.sample |  3 +
 src/bin/pg_basebackup/pg_createsubscriber.c   | 18 ++--
 .../t/040_pg_createsubscriber.pl              |  4 +-
 src/bin/pg_upgrade/check.c                    | 18 ++--
 src/bin/pg_upgrade/t/004_subscription.pl      | 17 ++--
 src/include/replication/origin.h              |  3 +
 12 files changed, 118 insertions(+), 90 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index fc186657a5..3f419e41be 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -4356,13 +4356,6 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
          to <literal>replica</literal> or higher to allow replication slots to
          be used.
         </para>
-
-        <para>
-         Note that this parameter also applies on the subscriber side, but with
-         a different meaning. See <xref linkend="guc-max-replication-slots-subscriber"/>
-         in <xref linkend="runtime-config-replication-subscriber"/> for more
-         details.
-        </para>
        </listitem>
       </varlistentry>
 
@@ -5068,10 +5061,10 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
 
      <variablelist>
 
-     <varlistentry id="guc-max-replication-slots-subscriber" xreflabel="max_replication_slots">
-      <term><varname>max_replication_slots</varname> (<type>integer</type>)
+     <varlistentry id="guc-max-replication-origin-sessions" xreflabel="max_replication_origin_sessions">
+      <term><varname>max_replication_origin_sessions</varname> (<type>integer</type>)
        <indexterm>
-        <primary><varname>max_replication_slots</varname> configuration parameter</primary>
+        <primary><varname>max_replication_origin_sessions</varname> configuration parameter</primary>
         <secondary>in a subscriber</secondary>
        </indexterm>
       </term>
@@ -5083,18 +5076,14 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
         be created on the server. Setting it to a lower value than the current
         number of tracked replication origins (reflected in
         <link linkend="view-pg-replication-origin-status">pg_replication_origin_status</link>)
-        will prevent the server from starting.
-        <literal>max_replication_slots</literal> must be set to at least the
+        will prevent the server from starting. It defaults to -1, indicating
+        that the value of <xref linkend="guc-max-replication-slots"/> should be
+        used instead. This parameter can only be set at server start.
+
+        <literal>max_replication_origin_sessions</literal> must be set to at least the
         number of subscriptions that will be added to the subscriber, plus some
         reserve for table synchronization.
        </para>
-
-       <para>
-        Note that this parameter also applies on a sending server, but with
-        a different meaning. See <xref linkend="guc-max-replication-slots"/>
-        in <xref linkend="runtime-config-replication-sender"/> for more
-        details.
-       </para>
       </listitem>
      </varlistentry>
 
diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml
index 613abcd28b..1e1e381c5c 100644
--- a/doc/src/sgml/logical-replication.sgml
+++ b/doc/src/sgml/logical-replication.sgml
@@ -2371,9 +2371,7 @@ CONTEXT:  processing remote data for replication origin "pg_16395" during "INSER
 
   <para>
    Logical replication requires several configuration options to be set. Most
-   options are relevant only on one side of the replication. However,
-   <varname>max_replication_slots</varname> is used on both the publisher and
-   the subscriber, but it has a different meaning for each.
+   options are relevant only on one side of the replication.
   </para>
 
   <sect2 id="logical-replication-config-publisher">
@@ -2408,7 +2406,7 @@ CONTEXT:  processing remote data for replication origin "pg_16395" during "INSER
    <title>Subscribers</title>
 
    <para>
-    <link linkend="guc-max-replication-slots-subscriber"><varname>max_replication_slots</varname></link>
+    <link linkend="guc-max-replication-origin-sessions"><varname>max_replication_origin_sessions</varname></link>
     must be set to at least the number of subscriptions that will be added to
     the subscriber, plus some reserve for table synchronization.
    </para>
diff --git a/doc/src/sgml/ref/pg_createsubscriber.sgml b/doc/src/sgml/ref/pg_createsubscriber.sgml
index 26b8e64a4e..a938390d50 100644
--- a/doc/src/sgml/ref/pg_createsubscriber.sgml
+++ b/doc/src/sgml/ref/pg_createsubscriber.sgml
@@ -295,7 +295,7 @@ PostgreSQL documentation
 
    <para>
     The target server must be used as a physical standby.  The target server
-    must have <xref linkend="guc-max-replication-slots"/> and <xref
+    must have <xref linkend="guc-max-replication-origin-sessions"/> and <xref
     linkend="guc-max-logical-replication-workers"/> configured to a value
     greater than or equal to the number of specified databases.  The target
     server must have <xref linkend="guc-max-worker-processes"/> configured to a
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index a3c7adbf1a..c4b3ab5b19 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -31,7 +31,7 @@
 #include "postmaster/bgworker.h"
 #include "postmaster/interrupt.h"
 #include "replication/logicallauncher.h"
-#include "replication/slot.h"
+#include "replication/origin.h"
 #include "replication/walreceiver.h"
 #include "replication/worker_internal.h"
 #include "storage/ipc.h"
@@ -325,10 +325,10 @@ logicalrep_worker_launch(LogicalRepWorkerType wtype,
 							 subname)));
 
 	/* Report this after the initial starting message for consistency. */
-	if (max_replication_slots == 0)
+	if (max_replication_origin_sessions == 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
-				 errmsg("cannot start logical replication workers when \"max_replication_slots\"=0")));
+				 errmsg("cannot start logical replication workers when \"max_replication_origin_sessions\"=0")));
 
 	/*
 	 * We need to do the modification of the shared memory under lock so that
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index 1b586cb1cf..def9031bf2 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -90,6 +90,7 @@
 #include "storage/lmgr.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
+#include "utils/guc.h"
 #include "utils/pg_lsn.h"
 #include "utils/rel.h"
 #include "utils/snapmgr.h"
@@ -99,6 +100,9 @@
 #define PG_REPLORIGIN_CHECKPOINT_FILENAME PG_LOGICAL_DIR "/replorigin_checkpoint"
 #define PG_REPLORIGIN_CHECKPOINT_TMPFILE PG_REPLORIGIN_CHECKPOINT_FILENAME ".tmp"
 
+/* GUC variables */
+int			max_replication_origin_sessions = -1;
+
 /*
  * Replay progress of a single remote node.
  */
@@ -151,7 +155,7 @@ typedef struct ReplicationStateCtl
 {
 	/* Tranche to use for per-origin LWLocks */
 	int			tranche_id;
-	/* Array of length max_replication_slots */
+	/* Array of length max_replication_origin_sessions */
 	ReplicationState states[FLEXIBLE_ARRAY_MEMBER];
 } ReplicationStateCtl;
 
@@ -162,10 +166,7 @@ TimestampTz replorigin_session_origin_timestamp = 0;
 
 /*
  * Base address into a shared memory array of replication states of size
- * max_replication_slots.
- *
- * XXX: Should we use a separate variable to size this rather than
- * max_replication_slots?
+ * max_replication_origin_sessions.
  */
 static ReplicationState *replication_states;
 
@@ -186,12 +187,12 @@ static ReplicationState *session_replication_state = NULL;
 #define REPLICATION_STATE_MAGIC ((uint32) 0x1257DADE)
 
 static void
-replorigin_check_prerequisites(bool check_slots, bool recoveryOK)
+replorigin_check_prerequisites(bool check_origins, bool recoveryOK)
 {
-	if (check_slots && max_replication_slots == 0)
+	if (check_origins && max_replication_origin_sessions == 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
-				 errmsg("cannot query or manipulate replication origin when \"max_replication_slots\" is 0")));
+				 errmsg("cannot query or manipulate replication origin when \"max_replication_origin_sessions\" is 0")));
 
 	if (!recoveryOK && RecoveryInProgress())
 		ereport(ERROR,
@@ -352,7 +353,7 @@ replorigin_state_clear(RepOriginId roident, bool nowait)
 restart:
 	LWLockAcquire(ReplicationOriginLock, LW_EXCLUSIVE);
 
-	for (i = 0; i < max_replication_slots; i++)
+	for (i = 0; i < max_replication_origin_sessions; i++)
 	{
 		ReplicationState *state = &replication_states[i];
 
@@ -511,18 +512,39 @@ ReplicationOriginShmemSize(void)
 {
 	Size		size = 0;
 
-	/*
-	 * XXX: max_replication_slots is arguably the wrong thing to use, as here
-	 * we keep the replay state of *remote* transactions. But for now it seems
-	 * sufficient to reuse it, rather than introduce a separate GUC.
-	 */
-	if (max_replication_slots == 0)
+	if (max_replication_origin_sessions == 0)
 		return size;
 
+	/*
+	 * Prior to PostgreSQL 18, max_replication_slots was used to set the
+	 * number of replication origins. For backward compatibility, -1 indicates
+	 * to use the fallback value (max_replication_slots).
+	 */
+	if (max_replication_origin_sessions == -1)
+	{
+		char		buf[32];
+
+		snprintf(buf, sizeof(buf), "%d", max_replication_slots);
+		SetConfigOption("max_replication_origin_sessions", buf,
+						PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT);
+
+		/*
+		 * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
+		 * However, if the DBA explicitly set max_replication_origin_sessions
+		 * equals to -1 in the config file, then PGC_S_DYNAMIC_DEFAULT will
+		 * fail to override that and we must force the matter with
+		 * PGC_S_OVERRIDE.
+		 */
+		if (max_replication_origin_sessions == -1)	/* failed to apply it? */
+			SetConfigOption("max_replication_origin_sessions", buf,
+							PGC_POSTMASTER, PGC_S_OVERRIDE);
+	}
+	Assert(max_replication_origin_sessions != -1);
+
 	size = add_size(size, offsetof(ReplicationStateCtl, states));
 
 	size = add_size(size,
-					mul_size(max_replication_slots, sizeof(ReplicationState)));
+					mul_size(max_replication_origin_sessions, sizeof(ReplicationState)));
 	return size;
 }
 
@@ -531,7 +553,7 @@ ReplicationOriginShmemInit(void)
 {
 	bool		found;
 
-	if (max_replication_slots == 0)
+	if (max_replication_origin_sessions == 0)
 		return;
 
 	replication_states_ctl = (ReplicationStateCtl *)
@@ -548,7 +570,7 @@ ReplicationOriginShmemInit(void)
 
 		replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN_STATE;
 
-		for (i = 0; i < max_replication_slots; i++)
+		for (i = 0; i < max_replication_origin_sessions; i++)
 		{
 			LWLockInitialize(&replication_states[i].lock,
 							 replication_states_ctl->tranche_id);
@@ -570,7 +592,7 @@ ReplicationOriginShmemInit(void)
  *
  * So its just the magic, followed by the statically sized
  * ReplicationStateOnDisk structs. Note that the maximum number of
- * ReplicationState is determined by max_replication_slots.
+ * ReplicationState is determined by max_replication_origin_sessions.
  * ---------------------------------------------------------------------------
  */
 void
@@ -583,7 +605,7 @@ CheckPointReplicationOrigin(void)
 	uint32		magic = REPLICATION_STATE_MAGIC;
 	pg_crc32c	crc;
 
-	if (max_replication_slots == 0)
+	if (max_replication_origin_sessions == 0)
 		return;
 
 	INIT_CRC32C(crc);
@@ -625,7 +647,7 @@ CheckPointReplicationOrigin(void)
 	LWLockAcquire(ReplicationOriginLock, LW_SHARED);
 
 	/* write actual data */
-	for (i = 0; i < max_replication_slots; i++)
+	for (i = 0; i < max_replication_origin_sessions; i++)
 	{
 		ReplicationStateOnDisk disk_state;
 		ReplicationState *curstate = &replication_states[i];
@@ -718,7 +740,7 @@ StartupReplicationOrigin(void)
 	already_started = true;
 #endif
 
-	if (max_replication_slots == 0)
+	if (max_replication_origin_sessions == 0)
 		return;
 
 	INIT_CRC32C(crc);
@@ -728,8 +750,8 @@ StartupReplicationOrigin(void)
 	fd = OpenTransientFile(path, O_RDONLY | PG_BINARY);
 
 	/*
-	 * might have had max_replication_slots == 0 last run, or we just brought
-	 * up a standby.
+	 * might have had max_replication_origin_sessions == 0 last run, or we
+	 * just brought up a standby.
 	 */
 	if (fd < 0 && errno == ENOENT)
 		return;
@@ -796,10 +818,10 @@ StartupReplicationOrigin(void)
 
 		COMP_CRC32C(crc, &disk_state, sizeof(disk_state));
 
-		if (last_state == max_replication_slots)
+		if (last_state == max_replication_origin_sessions)
 			ereport(PANIC,
 					(errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
-					 errmsg("could not find free replication state, increase \"max_replication_slots\"")));
+					 errmsg("could not find free replication state, increase \"max_replication_origin_sessions\"")));
 
 		/* copy data to shared memory */
 		replication_states[last_state].roident = disk_state.roident;
@@ -852,7 +874,7 @@ replorigin_redo(XLogReaderState *record)
 
 				xlrec = (xl_replorigin_drop *) XLogRecGetData(record);
 
-				for (i = 0; i < max_replication_slots; i++)
+				for (i = 0; i < max_replication_origin_sessions; i++)
 				{
 					ReplicationState *state = &replication_states[i];
 
@@ -917,7 +939,7 @@ replorigin_advance(RepOriginId node,
 	 * Search for either an existing slot for the origin, or a free one we can
 	 * use.
 	 */
-	for (i = 0; i < max_replication_slots; i++)
+	for (i = 0; i < max_replication_origin_sessions; i++)
 	{
 		ReplicationState *curstate = &replication_states[i];
 
@@ -958,7 +980,7 @@ replorigin_advance(RepOriginId node,
 				(errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
 				 errmsg("could not find free replication state slot for replication origin with ID %d",
 						node),
-				 errhint("Increase \"max_replication_slots\" and try again.")));
+				 errhint("Increase \"max_replication_origin_sessions\" and try again.")));
 
 	if (replication_state == NULL)
 	{
@@ -1024,7 +1046,7 @@ replorigin_get_progress(RepOriginId node, bool flush)
 	/* prevent slots from being concurrently dropped */
 	LWLockAcquire(ReplicationOriginLock, LW_SHARED);
 
-	for (i = 0; i < max_replication_slots; i++)
+	for (i = 0; i < max_replication_origin_sessions; i++)
 	{
 		ReplicationState *state;
 
@@ -1110,7 +1132,7 @@ replorigin_session_setup(RepOriginId node, int acquired_by)
 		registered_cleanup = true;
 	}
 
-	Assert(max_replication_slots > 0);
+	Assert(max_replication_origin_sessions > 0);
 
 	if (session_replication_state != NULL)
 		ereport(ERROR,
@@ -1124,7 +1146,7 @@ replorigin_session_setup(RepOriginId node, int acquired_by)
 	 * Search for either an existing slot for the origin, or a free one we can
 	 * use.
 	 */
-	for (i = 0; i < max_replication_slots; i++)
+	for (i = 0; i < max_replication_origin_sessions; i++)
 	{
 		ReplicationState *curstate = &replication_states[i];
 
@@ -1159,7 +1181,7 @@ replorigin_session_setup(RepOriginId node, int acquired_by)
 				(errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
 				 errmsg("could not find free replication state slot for replication origin with ID %d",
 						node),
-				 errhint("Increase \"max_replication_slots\" and try again.")));
+				 errhint("Increase \"max_replication_origin_sessions\" and try again.")));
 	else if (session_replication_state == NULL)
 	{
 		/* initialize new slot */
@@ -1195,7 +1217,7 @@ replorigin_session_reset(void)
 {
 	ConditionVariable *cv;
 
-	Assert(max_replication_slots != 0);
+	Assert(max_replication_origin_sessions != 0);
 
 	if (session_replication_state == NULL)
 		ereport(ERROR,
@@ -1536,7 +1558,7 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS)
 	 * filled. Note that we do not take any locks, so slightly corrupted/out
 	 * of date values are a possibility.
 	 */
-	for (i = 0; i < max_replication_slots; i++)
+	for (i = 0; i < max_replication_origin_sessions; i++)
 	{
 		ReplicationState *state;
 		Datum		values[REPLICATION_ORIGIN_PROGRESS_COLS];
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 382c774b24..94c83be74b 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -3280,6 +3280,18 @@ struct config_int ConfigureNamesInt[] =
 		NULL, NULL, NULL
 	},
 
+	{
+		{"max_replication_origin_sessions",
+			PGC_POSTMASTER,
+			REPLICATION_SUBSCRIBERS,
+			gettext_noop("Sets the maximum number of simultaneously configured replication origins."),
+			NULL
+		},
+		&max_replication_origin_sessions,
+		-1, -1, MAX_BACKENDS,
+		NULL, NULL, NULL
+	},
+
 	{
 		{"log_rotation_age", PGC_SIGHUP, LOGGING_WHERE,
 			gettext_noop("Sets the amount of time to wait before forcing "
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index f039eaa0c6..9363792c7c 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -378,6 +378,9 @@
 
 #max_logical_replication_workers = 4	# taken from max_worker_processes
 					# (change requires restart)
+#max_replication_origin_sessions = -1	# maximum number of configured replication origins
+					# -1 to use max_replication_slots
+					# (change requires restart)
 #max_sync_workers_per_subscription = 2	# taken from max_logical_replication_workers
 #max_parallel_apply_workers_per_subscription = 2	# taken from max_logical_replication_workers
 
diff --git a/src/bin/pg_basebackup/pg_createsubscriber.c b/src/bin/pg_basebackup/pg_createsubscriber.c
index faf18ccf13..b5e6bfa6e1 100644
--- a/src/bin/pg_basebackup/pg_createsubscriber.c
+++ b/src/bin/pg_basebackup/pg_createsubscriber.c
@@ -964,7 +964,7 @@ check_subscriber(const struct LogicalRepInfo *dbinfo)
 	bool		failed = false;
 
 	int			max_lrworkers;
-	int			max_repslots;
+	int			max_reporigins;
 	int			max_wprocs;
 
 	pg_log_info("checking settings on subscriber");
@@ -983,7 +983,7 @@ check_subscriber(const struct LogicalRepInfo *dbinfo)
 	 * Since these parameters are not a requirement for physical replication,
 	 * we should check it to make sure it won't fail.
 	 *
-	 * - max_replication_slots >= number of dbs to be converted
+	 * - max_replication_origin_sessions >= number of dbs to be converted
 	 * - max_logical_replication_workers >= number of dbs to be converted
 	 * - max_worker_processes >= 1 + number of dbs to be converted
 	 *------------------------------------------------------------------------
@@ -991,7 +991,7 @@ check_subscriber(const struct LogicalRepInfo *dbinfo)
 	res = PQexec(conn,
 				 "SELECT setting FROM pg_catalog.pg_settings WHERE name IN ("
 				 "'max_logical_replication_workers', "
-				 "'max_replication_slots', "
+				 "'max_replication_origin_sessions', "
 				 "'max_worker_processes', "
 				 "'primary_slot_name') "
 				 "ORDER BY name");
@@ -1004,14 +1004,14 @@ check_subscriber(const struct LogicalRepInfo *dbinfo)
 	}
 
 	max_lrworkers = atoi(PQgetvalue(res, 0, 0));
-	max_repslots = atoi(PQgetvalue(res, 1, 0));
+	max_reporigins = atoi(PQgetvalue(res, 1, 0));
 	max_wprocs = atoi(PQgetvalue(res, 2, 0));
 	if (strcmp(PQgetvalue(res, 3, 0), "") != 0)
 		primary_slot_name = pg_strdup(PQgetvalue(res, 3, 0));
 
 	pg_log_debug("subscriber: max_logical_replication_workers: %d",
 				 max_lrworkers);
-	pg_log_debug("subscriber: max_replication_slots: %d", max_repslots);
+	pg_log_debug("subscriber: max_replication_origin_sessions: %d", max_reporigins);
 	pg_log_debug("subscriber: max_worker_processes: %d", max_wprocs);
 	if (primary_slot_name)
 		pg_log_debug("subscriber: primary_slot_name: %s", primary_slot_name);
@@ -1020,12 +1020,12 @@ check_subscriber(const struct LogicalRepInfo *dbinfo)
 
 	disconnect_database(conn, false);
 
-	if (max_repslots < num_dbs)
+	if (max_reporigins < num_dbs)
 	{
-		pg_log_error("subscriber requires %d replication slots, but only %d remain",
-					 num_dbs, max_repslots);
+		pg_log_error("subscriber requires %d replication origin sessions, but only %d remain",
+					 num_dbs, max_reporigins);
 		pg_log_error_hint("Increase the configuration parameter \"%s\" to at least %d.",
-						  "max_replication_slots", num_dbs);
+						  "max_replication_origin_sessions", num_dbs);
 		failed = true;
 	}
 
diff --git a/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl b/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl
index c8dbdb7e9b..c64d5fbcc7 100644
--- a/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl
+++ b/src/bin/pg_basebackup/t/040_pg_createsubscriber.pl
@@ -274,7 +274,7 @@ max_worker_processes = 8
 # Check some unmet conditions on node S
 $node_s->append_conf(
 	'postgresql.conf', q{
-max_replication_slots = 1
+max_replication_origin_sessions = 1
 max_logical_replication_workers = 1
 max_worker_processes = 2
 });
@@ -293,7 +293,7 @@ command_fails(
 	'standby contains unmet conditions on node S');
 $node_s->append_conf(
 	'postgresql.conf', q{
-max_replication_slots = 10
+max_replication_origin_sessions = 10
 max_logical_replication_workers = 4
 max_worker_processes = 8
 });
diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c
index 7ca1d8fffc..4c9153e4a4 100644
--- a/src/bin/pg_upgrade/check.c
+++ b/src/bin/pg_upgrade/check.c
@@ -1815,16 +1815,16 @@ check_new_cluster_logical_replication_slots(void)
 /*
  * check_new_cluster_subscription_configuration()
  *
- * Verify that the max_replication_slots configuration specified is enough for
- * creating the subscriptions. This is required to create the replication
- * origin for each subscription.
+ * Verify that the max_replication_origin_sessions configuration specified is
+ * enough for creating the subscriptions. This is required to create the
+ * replication origin for each subscription.
  */
 static void
 check_new_cluster_subscription_configuration(void)
 {
 	PGresult   *res;
 	PGconn	   *conn;
-	int			max_replication_slots;
+	int			max_replication_origin_sessions;
 
 	/* Subscriptions and their dependencies can be migrated since PG17. */
 	if (GET_MAJOR_VERSION(old_cluster.major_version) < 1700)
@@ -1839,16 +1839,16 @@ check_new_cluster_subscription_configuration(void)
 	conn = connectToServer(&new_cluster, "template1");
 
 	res = executeQueryOrDie(conn, "SELECT setting FROM pg_settings "
-							"WHERE name = 'max_replication_slots';");
+							"WHERE name = 'max_replication_origin_sessions';");
 
 	if (PQntuples(res) != 1)
 		pg_fatal("could not determine parameter settings on new cluster");
 
-	max_replication_slots = atoi(PQgetvalue(res, 0, 0));
-	if (old_cluster.nsubs > max_replication_slots)
-		pg_fatal("\"max_replication_slots\" (%d) must be greater than or equal to the number of "
+	max_replication_origin_sessions = atoi(PQgetvalue(res, 0, 0));
+	if (old_cluster.nsubs > max_replication_origin_sessions)
+		pg_fatal("\"max_replication_origin_sessions\" (%d) must be greater than or equal to the number of "
 				 "subscriptions (%d) on the old cluster",
-				 max_replication_slots, old_cluster.nsubs);
+				 max_replication_origin_sessions, old_cluster.nsubs);
 
 	PQclear(res);
 	PQfinish(conn);
diff --git a/src/bin/pg_upgrade/t/004_subscription.pl b/src/bin/pg_upgrade/t/004_subscription.pl
index 13773316e1..27c9adeded 100644
--- a/src/bin/pg_upgrade/t/004_subscription.pl
+++ b/src/bin/pg_upgrade/t/004_subscription.pl
@@ -41,8 +41,9 @@ chdir ${PostgreSQL::Test::Utils::tmp_check};
 my $connstr = $publisher->connstr . ' dbname=postgres';
 
 # ------------------------------------------------------
-# Check that pg_upgrade fails when max_replication_slots configured in the new
-# cluster is less than the number of subscriptions in the old cluster.
+# Check that pg_upgrade fails when max_replication_origin_sessions configured
+# in the new cluster is less than the number of subscriptions in the old
+# cluster.
 # ------------------------------------------------------
 # It is sufficient to use disabled subscription to test upgrade failure.
 $publisher->safe_psql('postgres', "CREATE PUBLICATION regress_pub1");
@@ -52,10 +53,10 @@ $old_sub->safe_psql('postgres',
 
 $old_sub->stop;
 
-$new_sub->append_conf('postgresql.conf', "max_replication_slots = 0");
+$new_sub->append_conf('postgresql.conf', "max_replication_origin_sessions = 0");
 
 # pg_upgrade will fail because the new cluster has insufficient
-# max_replication_slots.
+# max_replication_origin_sessions.
 command_checks_all(
 	[
 		'pg_upgrade',
@@ -72,14 +73,14 @@ command_checks_all(
 	],
 	1,
 	[
-		qr/"max_replication_slots" \(0\) must be greater than or equal to the number of subscriptions \(1\) on the old cluster/
+		qr/"max_replication_origin_sessions" \(0\) must be greater than or equal to the number of subscriptions \(1\) on the old cluster/
 	],
 	[qr//],
-	'run of pg_upgrade where the new cluster has insufficient max_replication_slots'
+	'run of pg_upgrade where the new cluster has insufficient max_replication_origin_sessions'
 );
 
-# Reset max_replication_slots
-$new_sub->append_conf('postgresql.conf', "max_replication_slots = 10");
+# Reset max_replication_origin_sessions
+$new_sub->append_conf('postgresql.conf', "max_replication_origin_sessions = 10");
 
 # Cleanup
 $publisher->safe_psql('postgres', "DROP PUBLICATION regress_pub1");
diff --git a/src/include/replication/origin.h b/src/include/replication/origin.h
index 33a7e59ddb..bd3fd9ce5e 100644
--- a/src/include/replication/origin.h
+++ b/src/include/replication/origin.h
@@ -37,6 +37,9 @@ extern PGDLLIMPORT RepOriginId replorigin_session_origin;
 extern PGDLLIMPORT XLogRecPtr replorigin_session_origin_lsn;
 extern PGDLLIMPORT TimestampTz replorigin_session_origin_timestamp;
 
+/* GUCs */
+extern PGDLLIMPORT int max_replication_origin_sessions;
+
 /* API for querying & manipulating replication origins */
 extern RepOriginId replorigin_by_name(const char *roname, bool missing_ok);
 extern RepOriginId replorigin_create(const char *roname);
-- 
2.39.5

Reply via email to