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