Patch for reserved connections for replication users
Hi,
this patch introduces a new configuration flag
replication_reserved_connections to reserve connection slots for
replication in the same way superuser_reserved_connections works for
superusers.
This helps in cases where the application opens connections until
max_connections is reached. A slave would not be able to connect to the
master now and would just be down. With this patch the slave is able to
connect.
This option does not influence the superuser_reserved_connections, so
new slaves are not able to open new connections when the reserved
replication slots are filled.
The only thing this patch is missing are tests. Where should I put them
into the source tree?
thank you,
Stefan Radomski
Attachments:
replication_reserved_connections.patchtext/x-patchDownload
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
new file mode 100644
index 6a4d15f..cd6264e
*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
*************** include 'filename'
*** 530,535 ****
--- 530,562 ----
</listitem>
</varlistentry>
+ <varlistentry id="guc-replication_reserved_connections"
+ xreflabel="replication_reserved_connections">
+ <term><varname>replication_reserved_connections</varname></term>
+ (<type>integer</type>)</term>
+ <indexterm>
+ <primary><varname>replication_reserved_connections</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ Determines the number of connection <quote>slots</quote> that
+ are reserved for connections by <productname>PostgreSQL</>
+ replication users. At most <xref linkend="guc-max-connections">
+ connections can ever be active simultaneously. Whenever the
+ number of active concurrent connections is at least
+ <varname>max_connections</> minus
+ <varname>superuser_reserved_connections</varname> minus
+ <varname>replication_reserved_connections</varname>, new
+ connections will be accepted only for replication and superusers.
+ </para>
+
+ <para>
+ The default value is zero connections. The value must be less
+ than the value of <varname>max_connections</varname>. This
+ parameter can only be set at server start.
+ </para>
+ </varlistentry>
+
<varlistentry id="guc-unix-socket-directories" xreflabel="unix_socket_directories">
<term><varname>unix_socket_directories</varname> (<type>string</type>)</term>
<indexterm>
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
new file mode 100644
index 496192d..ce37b0d
*** a/src/backend/postmaster/postmaster.c
--- b/src/backend/postmaster/postmaster.c
*************** char *ListenAddresses;
*** 224,229 ****
--- 224,238 ----
* count against the limit.
*/
int ReservedBackends;
+ /*
+ * ReservedReplicationBackends is the number of backends reserved for
+ * replication user use. Like ReservedBackends the number will be taken out
+ * of the pool size given by MaxBackends so the number available to
+ * non-superusers is
+ * (MaxBackends - ReservedBackends - ReservedReplicationBackends).
+ * This option does not block superusers.
+ */
+ int ReservedReplicationBackends;
/* The socket(s) we're listening to. */
#define MAXLISTEN 64
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
new file mode 100644
index 2c7f0f1..d0f8f91
*** a/src/backend/utils/init/postinit.c
--- b/src/backend/utils/init/postinit.c
*************** InitPostgres(const char *in_dbname, Oid
*** 700,707 ****
}
/*
! * The last few connections slots are reserved for superusers. Although
! * replication connections currently require superuser privileges, we
* don't allow them to consume the reserved slots, which are intended for
* interactive use.
*/
--- 700,716 ----
}
/*
! * The last few connections slots are reserved for superusers and replication.
! */
! if (!am_superuser &&
! (ReservedReplicationBackends > 0 || ReservedBackends > 0) &&
! !HaveNFreeProcs(ReservedReplicationBackends + ReservedBackends))
! ereport(FATAL,
! (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
! errmsg("remaining connection slots are reserved for replication and superuser connections")));
!
! /*
! * Although replication connections currently require superuser privileges, we
* don't allow them to consume the reserved slots, which are intended for
* interactive use.
*/
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
new file mode 100644
index 5aefd1b..b03d722
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
*************** static struct config_int ConfigureNamesI
*** 1633,1638 ****
--- 1633,1647 ----
3, 0, MAX_BACKENDS,
NULL, NULL, NULL
},
+ {
+ {"replication_reserved_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS,
+ gettext_noop("Sets the number of connection slots reserved for replication."),
+ NULL
+ },
+ &ReservedReplicationBackends,
+ 1, 0, MAX_BACKENDS,
+ NULL, NULL, NULL
+ },
/*
* We sometimes multiply the number of shared buffers by two without
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
new file mode 100644
index d69a02b..0be67af
*** a/src/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 65,70 ****
--- 65,71 ----
# Note: Increasing max_connections costs ~400 bytes of shared memory per
# connection slot, plus lock space (see max_locks_per_transaction).
#superuser_reserved_connections = 3 # (change requires restart)
+ #replication_reserved_connections = 0 # (change requires restart)
#unix_socket_directories = '/tmp' # comma-separated list of directories
# (change requires restart)
#unix_socket_group = '' # (change requires restart)
diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h
new file mode 100644
index c090595..dd2f049
*** a/src/include/postmaster/postmaster.h
--- b/src/include/postmaster/postmaster.h
***************
*** 16,21 ****
--- 16,22 ----
/* GUC options */
extern bool EnableSSL;
extern int ReservedBackends;
+ extern int ReservedReplicationBackends;
extern int PostPortNumber;
extern int Unix_socket_permissions;
extern char *Unix_socket_group;
Hi,
here is an update off my patch based on the discussion with Marko
Tiikkaja and Andres Freund.
Marko and I had the idea of introducing reserved connections based on
roles as it would create a way to garantuee specific roles to connect
when other roles use up all connections for whatever reason. But
Andreas said, that it would make connecting take much too long.
So to just fix the issue at hand, we decided that adding
max_wal_senders to the pool of reserved connections is better. With
that, we are sure that streaming replication can connect to the master.
So instead of creating a new configuration option I added
max_wal_senders to the reserved connections and changed the check for
new connections.
The test.pl is a small script to test, if the patch does what it should.
regards,
Stefan Radomski
Attachments:
replication_reserved_connections-v2.patchtext/x-patchDownload
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 23ebc11..2ba98e2 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -2170,8 +2170,10 @@ include 'filename'
processes). The default is zero, meaning replication is
disabled. WAL sender processes count towards the total number
of connections, so the parameter cannot be set higher than
- <xref linkend="guc-max-connections">. This parameter can only
- be set at server start. <varname>wal_level</> must be set
+ <xref linkend="guc-max-connections">. Like
+ <xref linkend="guc-superuser-reserved-connections"> this option reserves
+ connections from <xref linkend="guc-max-connections">. This parameter
+ can only be set at server start. <varname>wal_level</> must be set
to <literal>archive</> or <literal>hot_standby</> to allow
connections from standby servers.
</para>
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 2c7f0f1..3194894 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -436,7 +436,7 @@ InitializeMaxBackends(void)
/* the extra unit accounts for the autovacuum launcher */
MaxBackends = MaxConnections + autovacuum_max_workers + 1 +
- + max_worker_processes;
+ + max_worker_processes + max_wal_senders;
/* internal error because the values were all checked previously */
if (MaxBackends > MAX_BACKENDS)
@@ -705,7 +705,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
* don't allow them to consume the reserved slots, which are intended for
* interactive use.
*/
- if ((!am_superuser || am_walsender) &&
+ if ((!am_superuser && !am_walsender) &&
ReservedBackends > 0 &&
!HaveNFreeProcs(ReservedBackends))
ereport(FATAL,
On Tue, Jul 30, 2013 at 3:10 AM, Gibheer <gibheer@zero-knowledge.org> wrote:
here is an update off my patch based on the discussion with Marko
Tiikkaja and Andres Freund.Marko and I had the idea of introducing reserved connections based on
roles as it would create a way to garantuee specific roles to connect
when other roles use up all connections for whatever reason. But
Andreas said, that it would make connecting take much too long.So to just fix the issue at hand, we decided that adding
max_wal_senders to the pool of reserved connections is better. With
that, we are sure that streaming replication can connect to the master.So instead of creating a new configuration option I added
max_wal_senders to the reserved connections and changed the check for
new connections.The test.pl is a small script to test, if the patch does what it should.
Hmm. It seems like this match is making MaxConnections no longer mean
the maximum number of connections, but rather the maximum number of
non-replication connections. I don't think I support that
definitional change, and I'm kinda surprised if this is sufficient to
implement it anyway (e.g. see InitProcGlobal()).
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Fri, 2 Aug 2013 08:16:15 -0400
Robert Haas <robertmhaas@gmail.com> wrote:
On Tue, Jul 30, 2013 at 3:10 AM, Gibheer <gibheer@zero-knowledge.org>
wrote:here is an update off my patch based on the discussion with Marko
Tiikkaja and Andres Freund.Marko and I had the idea of introducing reserved connections based
on roles as it would create a way to garantuee specific roles to
connect when other roles use up all connections for whatever
reason. But Andreas said, that it would make connecting take much
too long.So to just fix the issue at hand, we decided that adding
max_wal_senders to the pool of reserved connections is better. With
that, we are sure that streaming replication can connect to the
master.So instead of creating a new configuration option I added
max_wal_senders to the reserved connections and changed the check
for new connections.The test.pl is a small script to test, if the patch does what it
should.Hmm. It seems like this match is making MaxConnections no longer mean
the maximum number of connections, but rather the maximum number of
non-replication connections. I don't think I support that
definitional change, and I'm kinda surprised if this is sufficient to
implement it anyway (e.g. see InitProcGlobal()).
You are right, that can't be correct. The slots I added with
max_wal_sender would end up as background worker slots. I have to check
my tests again.
In my first patch I just copied the part to limit the connections based
on superuser reserved connections + replication reserved connections.
That did not change the definition of max_connections and made
superuser connections higher in priority than replication connections.
Is that the better approach?
Thank you for your input.
Stefan
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2013-08-02 08:16:15 -0400, Robert Haas wrote:
On Tue, Jul 30, 2013 at 3:10 AM, Gibheer <gibheer@zero-knowledge.org> wrote:
here is an update off my patch based on the discussion with Marko
Tiikkaja and Andres Freund.Marko and I had the idea of introducing reserved connections based on
roles as it would create a way to garantuee specific roles to connect
when other roles use up all connections for whatever reason. But
Andreas said, that it would make connecting take much too long.So to just fix the issue at hand, we decided that adding
max_wal_senders to the pool of reserved connections is better. With
that, we are sure that streaming replication can connect to the master.So instead of creating a new configuration option I added
max_wal_senders to the reserved connections and changed the check for
new connections.The test.pl is a small script to test, if the patch does what it should.
Hmm. It seems like this match is making MaxConnections no longer mean
the maximum number of connections, but rather the maximum number of
non-replication connections. I don't think I support that
definitional change, and I'm kinda surprised if this is sufficient to
implement it anyway (e.g. see InitProcGlobal()).
I don't think the implementation is correct, but why don't you like the
definitional change? The set of things you can do from replication
connections are completely different from a normal connection. So using
separate "pools" for them seems to make sense.
That they end up allocating similar internal data seems to be an
implementation detail to me.
Greetings,
Andres Freund
--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Mon, Aug 5, 2013 at 2:04 AM, Andres Freund <andres@2ndquadrant.com> wrote:
Hmm. It seems like this match is making MaxConnections no longer mean
the maximum number of connections, but rather the maximum number of
non-replication connections. I don't think I support that
definitional change, and I'm kinda surprised if this is sufficient to
implement it anyway (e.g. see InitProcGlobal()).I don't think the implementation is correct, but why don't you like the
definitional change? The set of things you can do from replication
connections are completely different from a normal connection. So using
separate "pools" for them seems to make sense.
That they end up allocating similar internal data seems to be an
implementation detail to me.
Because replication connections are still "connections". If I tell
the system I want to allow 100 connections to the server, it should
allow 100 connections, not 110 or 95 or any other number.
I'm also not sure the decision about whether something is a WAL sender
is made early enough for the distinction to really make sense. WAL
senders actually start off, from the postmaster's POV, as regular
backends, and then become walsenders "on the fly".
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers