[PATCH v1 1/1] max_active_replication_origins fix

Nathan Bossart <nathan@postgresql.org>

From: Nathan Bossart <nathan@postgresql.org>
To:
Date: 2025-09-17T02:56:27Z
Lists: pgsql-bugs
---
 doc/src/sgml/config.sgml                | 5 +++++
 doc/src/sgml/high-availability.sgml     | 5 +++++
 src/backend/access/rmgrdesc/xlogdesc.c  | 2 ++
 src/backend/access/transam/xlog.c       | 8 ++++++++
 src/bin/pg_controldata/pg_controldata.c | 2 ++
 src/bin/pg_resetwal/pg_resetwal.c       | 2 ++
 src/include/access/xlog_internal.h      | 3 ++-
 src/include/catalog/pg_control.h        | 3 ++-
 8 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index e9b420f3ddb..c85858e9c8a 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -5322,6 +5322,11 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
         number of subscriptions that will be added to the subscriber, plus some
         reserve for table synchronization.
        </para>
+       <para>
+        When running a standby server, you must set this parameter to the same
+        or higher value than on the primary server.  Otherwise, queries will
+        not be allowed in the standby server.
+       </para>
       </listitem>
      </varlistentry>
 
diff --git a/doc/src/sgml/high-availability.sgml b/doc/src/sgml/high-availability.sgml
index b47d8b4106e..ffc1ba4e534 100644
--- a/doc/src/sgml/high-availability.sgml
+++ b/doc/src/sgml/high-availability.sgml
@@ -2026,6 +2026,11 @@ LOG:  database system is ready to accept read-only connections
          <varname>max_locks_per_transaction</varname>
         </para>
        </listitem>
+       <listitem>
+        <para>
+         <varname>max_active_replication_origins</varname>
+        </para>
+       </listitem>
        <listitem>
         <para>
          <varname>max_wal_senders</varname>
diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c
index cd6c2a2f650..7021f512093 100644
--- a/src/backend/access/rmgrdesc/xlogdesc.c
+++ b/src/backend/access/rmgrdesc/xlogdesc.c
@@ -124,6 +124,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
 		appendStringInfo(buf, "max_connections=%d max_worker_processes=%d "
 						 "max_wal_senders=%d max_prepared_xacts=%d "
 						 "max_locks_per_xact=%d wal_level=%s "
+						 "max_active_replication_origins=%d "
 						 "wal_log_hints=%s track_commit_timestamp=%s",
 						 xlrec.MaxConnections,
 						 xlrec.max_worker_processes,
@@ -131,6 +132,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
 						 xlrec.max_prepared_xacts,
 						 xlrec.max_locks_per_xact,
 						 wal_level_str,
+						 xlrec.max_active_replication_origins,
 						 xlrec.wal_log_hints ? "on" : "off",
 						 xlrec.track_commit_timestamp ? "on" : "off");
 	}
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 0baf0ac6160..38f5203b144 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -4225,6 +4225,7 @@ InitControlFile(uint64 sysidentifier, uint32 data_checksum_version)
 	ControlFile->max_wal_senders = max_wal_senders;
 	ControlFile->max_prepared_xacts = max_prepared_xacts;
 	ControlFile->max_locks_per_xact = max_locks_per_xact;
+	ControlFile->max_active_replication_origins = max_active_replication_origins;
 	ControlFile->wal_level = wal_level;
 	ControlFile->wal_log_hints = wal_log_hints;
 	ControlFile->track_commit_timestamp = track_commit_timestamp;
@@ -5439,6 +5440,9 @@ CheckRequiredParameterValues(void)
 		RecoveryRequiresIntParameter("max_locks_per_transaction",
 									 max_locks_per_xact,
 									 ControlFile->max_locks_per_xact);
+		RecoveryRequiresIntParameter("max_active_replication_origins",
+									 max_active_replication_origins,
+									 ControlFile->max_active_replication_origins);
 	}
 }
 
@@ -8141,6 +8145,7 @@ XLogReportParameters(void)
 		max_wal_senders != ControlFile->max_wal_senders ||
 		max_prepared_xacts != ControlFile->max_prepared_xacts ||
 		max_locks_per_xact != ControlFile->max_locks_per_xact ||
+		max_active_replication_origins != ControlFile->max_active_replication_origins ||
 		track_commit_timestamp != ControlFile->track_commit_timestamp)
 	{
 		/*
@@ -8160,6 +8165,7 @@ XLogReportParameters(void)
 			xlrec.max_wal_senders = max_wal_senders;
 			xlrec.max_prepared_xacts = max_prepared_xacts;
 			xlrec.max_locks_per_xact = max_locks_per_xact;
+			xlrec.max_active_replication_origins = max_active_replication_origins;
 			xlrec.wal_level = wal_level;
 			xlrec.wal_log_hints = wal_log_hints;
 			xlrec.track_commit_timestamp = track_commit_timestamp;
@@ -8178,6 +8184,7 @@ XLogReportParameters(void)
 		ControlFile->max_wal_senders = max_wal_senders;
 		ControlFile->max_prepared_xacts = max_prepared_xacts;
 		ControlFile->max_locks_per_xact = max_locks_per_xact;
+		ControlFile->max_active_replication_origins = max_active_replication_origins;
 		ControlFile->wal_level = wal_level;
 		ControlFile->wal_log_hints = wal_log_hints;
 		ControlFile->track_commit_timestamp = track_commit_timestamp;
@@ -8560,6 +8567,7 @@ xlog_redo(XLogReaderState *record)
 		ControlFile->max_wal_senders = xlrec.max_wal_senders;
 		ControlFile->max_prepared_xacts = xlrec.max_prepared_xacts;
 		ControlFile->max_locks_per_xact = xlrec.max_locks_per_xact;
+		ControlFile->max_active_replication_origins = xlrec.max_active_replication_origins;
 		ControlFile->wal_level = xlrec.wal_level;
 		ControlFile->wal_log_hints = xlrec.wal_log_hints;
 
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 10de058ce91..287e7e5492c 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -308,6 +308,8 @@ main(int argc, char *argv[])
 		   ControlFile->max_prepared_xacts);
 	printf(_("max_locks_per_xact setting:           %d\n"),
 		   ControlFile->max_locks_per_xact);
+	printf(_("max_active_replication_origins setting:%d\n"),
+		   ControlFile->max_active_replication_origins);
 	printf(_("track_commit_timestamp setting:       %s\n"),
 		   ControlFile->track_commit_timestamp ? _("on") : _("off"));
 	printf(_("Maximum data alignment:               %u\n"),
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index 7a4e4eb9570..6afa37c8af3 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -708,6 +708,7 @@ GuessControlValues(void)
 	ControlFile.max_worker_processes = 8;
 	ControlFile.max_prepared_xacts = 0;
 	ControlFile.max_locks_per_xact = 64;
+	ControlFile.max_active_replication_origins = 10;
 
 	ControlFile.maxAlign = MAXIMUM_ALIGNOF;
 	ControlFile.floatFormat = FLOATFORMAT_VALUE;
@@ -913,6 +914,7 @@ RewriteControlFile(void)
 	ControlFile.max_worker_processes = 8;
 	ControlFile.max_prepared_xacts = 0;
 	ControlFile.max_locks_per_xact = 64;
+	ControlFile.max_active_replication_origins = 10;
 
 	/* The control file gets flushed here. */
 	update_controlfile(".", &ControlFile, true);
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index cc06fc29ab2..0a48b78724d 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -31,7 +31,7 @@
 /*
  * Each page of XLOG file has a header like this:
  */
-#define XLOG_PAGE_MAGIC 0xD118	/* can be used as WAL version indicator */
+#define XLOG_PAGE_MAGIC 0xD119	/* can be used as WAL version indicator */
 
 typedef struct XLogPageHeaderData
 {
@@ -277,6 +277,7 @@ typedef struct xl_parameter_change
 	int			max_wal_senders;
 	int			max_prepared_xacts;
 	int			max_locks_per_xact;
+	int			max_active_replication_origins;
 	int			wal_level;
 	bool		wal_log_hints;
 	bool		track_commit_timestamp;
diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h
index 63e834a6ce4..55952f52e6a 100644
--- a/src/include/catalog/pg_control.h
+++ b/src/include/catalog/pg_control.h
@@ -22,7 +22,7 @@
 
 
 /* Version identifier for this pg_control format */
-#define PG_CONTROL_VERSION	1800
+#define PG_CONTROL_VERSION	1801
 
 /* Nonce key length, see below */
 #define MOCK_AUTH_NONCE_LEN		32
@@ -182,6 +182,7 @@ typedef struct ControlFileData
 	int			max_wal_senders;
 	int			max_prepared_xacts;
 	int			max_locks_per_xact;
+	int			max_active_replication_origins;
 	bool		track_commit_timestamp;
 
 	/*
-- 
2.39.5 (Apple Git-154)


--k8NvjNX9R4oGarBA--