mirror of
https://github.com/postgres/postgres.git
synced 2025-11-07 19:06:32 +03:00
Move max_wal_senders out of max_connections for connection slot handling
Since its introduction, max_wal_senders is counted as part of max_connections when it comes to define how many connection slots can be used for replication connections with a WAL sender context. This can lead to confusion for some users, as it could be possible to block a base backup or replication from happening because other backend sessions are already taken for other purposes by an application, and superuser-only connection slots are not a correct solution to handle that case. This commit makes max_wal_senders independent of max_connections for its handling of PGPROC entries in ProcGlobal, meaning that connection slots for WAL senders are handled using their own free queue, like autovacuum workers and bgworkers. One compatibility issue that this change creates is that a standby now requires to have a value of max_wal_senders at least equal to its primary. So, if a standby created enforces the value of max_wal_senders to be lower than that, then this could break failovers. Normally this should not be an issue though, as any settings of a standby are inherited from its primary as postgresql.conf gets normally copied as part of a base backup, so parameters would be consistent. Author: Alexander Kukushkin Reviewed-by: Kyotaro Horiguchi, Petr Jelínek, Masahiko Sawada, Oleksii Kliukin Discussion: https://postgr.es/m/CAFh8B=nBzHQeYAu0b8fjK-AF1X4+_p6GRtwG+cCgs6Vci2uRuQ@mail.gmail.com
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
#include "postmaster/autovacuum.h"
|
||||
#include "replication/slot.h"
|
||||
#include "replication/syncrep.h"
|
||||
#include "replication/walsender.h"
|
||||
#include "storage/condition_variable.h"
|
||||
#include "storage/standby.h"
|
||||
#include "storage/ipc.h"
|
||||
@@ -147,8 +148,9 @@ ProcGlobalSemas(void)
|
||||
* running out when trying to start another backend is a common failure.
|
||||
* So, now we grab enough semaphores to support the desired max number
|
||||
* of backends immediately at initialization --- if the sysadmin has set
|
||||
* MaxConnections, max_worker_processes, or autovacuum_max_workers higher
|
||||
* than his kernel will support, he'll find out sooner rather than later.
|
||||
* MaxConnections, max_worker_processes, max_wal_senders, or
|
||||
* autovacuum_max_workers higher than his kernel will support, he'll
|
||||
* find out sooner rather than later.
|
||||
*
|
||||
* Another reason for creating semaphores here is that the semaphore
|
||||
* implementation typically requires us to create semaphores in the
|
||||
@@ -180,6 +182,7 @@ InitProcGlobal(void)
|
||||
ProcGlobal->freeProcs = NULL;
|
||||
ProcGlobal->autovacFreeProcs = NULL;
|
||||
ProcGlobal->bgworkerFreeProcs = NULL;
|
||||
ProcGlobal->walsenderFreeProcs = NULL;
|
||||
ProcGlobal->startupProc = NULL;
|
||||
ProcGlobal->startupProcPid = 0;
|
||||
ProcGlobal->startupBufferPinWaitBufId = -1;
|
||||
@@ -253,13 +256,20 @@ InitProcGlobal(void)
|
||||
ProcGlobal->autovacFreeProcs = &procs[i];
|
||||
procs[i].procgloballist = &ProcGlobal->autovacFreeProcs;
|
||||
}
|
||||
else if (i < MaxBackends)
|
||||
else if (i < MaxConnections + autovacuum_max_workers + 1 + max_worker_processes)
|
||||
{
|
||||
/* PGPROC for bgworker, add to bgworkerFreeProcs list */
|
||||
procs[i].links.next = (SHM_QUEUE *) ProcGlobal->bgworkerFreeProcs;
|
||||
ProcGlobal->bgworkerFreeProcs = &procs[i];
|
||||
procs[i].procgloballist = &ProcGlobal->bgworkerFreeProcs;
|
||||
}
|
||||
else if (i < MaxBackends)
|
||||
{
|
||||
/* PGPROC for walsender, add to walsenderFreeProcs list */
|
||||
procs[i].links.next = (SHM_QUEUE *) ProcGlobal->walsenderFreeProcs;
|
||||
ProcGlobal->walsenderFreeProcs = &procs[i];
|
||||
procs[i].procgloballist = &ProcGlobal->walsenderFreeProcs;
|
||||
}
|
||||
|
||||
/* Initialize myProcLocks[] shared memory queues. */
|
||||
for (j = 0; j < NUM_LOCK_PARTITIONS; j++)
|
||||
@@ -311,6 +321,8 @@ InitProcess(void)
|
||||
procgloballist = &ProcGlobal->autovacFreeProcs;
|
||||
else if (IsBackgroundWorker)
|
||||
procgloballist = &ProcGlobal->bgworkerFreeProcs;
|
||||
else if (am_walsender)
|
||||
procgloballist = &ProcGlobal->walsenderFreeProcs;
|
||||
else
|
||||
procgloballist = &ProcGlobal->freeProcs;
|
||||
|
||||
@@ -341,6 +353,11 @@ InitProcess(void)
|
||||
* in the autovacuum case?
|
||||
*/
|
||||
SpinLockRelease(ProcStructLock);
|
||||
if (am_walsender)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
|
||||
errmsg("number of requested standby connections exceeds max_wal_senders (currently %d)",
|
||||
max_wal_senders)));
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
|
||||
errmsg("sorry, too many clients already")));
|
||||
|
||||
Reference in New Issue
Block a user