[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--