mirror of
https://github.com/postgres/postgres.git
synced 2025-08-30 06:01:21 +03:00
Don't count background workers against a user's connection limit.
Doing so doesn't seem to be within the purpose of the per user connection limits, and has particularly unfortunate effects in conjunction with parallel queries. Backpatch to 9.6 where parallel queries were introduced. David Rowley, reviewed by Robert Haas and Albe Laurenz.
This commit is contained in:
@@ -420,6 +420,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
|
||||
proc->backendId = InvalidBackendId;
|
||||
proc->databaseId = databaseid;
|
||||
proc->roleId = owner;
|
||||
proc->isBackgroundWorker = false;
|
||||
proc->lwWaiting = false;
|
||||
proc->lwWaitMode = 0;
|
||||
proc->waitLock = NULL;
|
||||
|
@@ -2751,6 +2751,38 @@ CountDBBackends(Oid databaseid)
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* CountDBConnections --- counts database backends ignoring any background
|
||||
* worker processes
|
||||
*/
|
||||
int
|
||||
CountDBConnections(Oid databaseid)
|
||||
{
|
||||
ProcArrayStruct *arrayP = procArray;
|
||||
int count = 0;
|
||||
int index;
|
||||
|
||||
LWLockAcquire(ProcArrayLock, LW_SHARED);
|
||||
|
||||
for (index = 0; index < arrayP->numProcs; index++)
|
||||
{
|
||||
int pgprocno = arrayP->pgprocnos[index];
|
||||
volatile PGPROC *proc = &allProcs[pgprocno];
|
||||
|
||||
if (proc->pid == 0)
|
||||
continue; /* do not count prepared xacts */
|
||||
if (proc->isBackgroundWorker)
|
||||
continue; /* do not count background workers */
|
||||
if (!OidIsValid(databaseid) ||
|
||||
proc->databaseId == databaseid)
|
||||
count++;
|
||||
}
|
||||
|
||||
LWLockRelease(ProcArrayLock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* CancelDBBackends --- cancel backends that are using specified database
|
||||
*/
|
||||
@@ -2810,6 +2842,8 @@ CountUserBackends(Oid roleid)
|
||||
|
||||
if (proc->pid == 0)
|
||||
continue; /* do not count prepared xacts */
|
||||
if (proc->isBackgroundWorker)
|
||||
continue; /* do not count background workers */
|
||||
if (proc->roleId == roleid)
|
||||
count++;
|
||||
}
|
||||
|
@@ -372,6 +372,7 @@ InitProcess(void)
|
||||
MyProc->backendId = InvalidBackendId;
|
||||
MyProc->databaseId = InvalidOid;
|
||||
MyProc->roleId = InvalidOid;
|
||||
MyProc->isBackgroundWorker = IsBackgroundWorker;
|
||||
MyPgXact->delayChkpt = false;
|
||||
MyPgXact->vacuumFlags = 0;
|
||||
/* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
|
||||
@@ -544,6 +545,7 @@ InitAuxiliaryProcess(void)
|
||||
MyProc->backendId = InvalidBackendId;
|
||||
MyProc->databaseId = InvalidOid;
|
||||
MyProc->roleId = InvalidOid;
|
||||
MyProc->isBackgroundWorker = IsBackgroundWorker;
|
||||
MyPgXact->delayChkpt = false;
|
||||
MyPgXact->vacuumFlags = 0;
|
||||
MyProc->lwWaiting = false;
|
||||
|
@@ -350,7 +350,7 @@ CheckMyDatabase(const char *name, bool am_superuser)
|
||||
*/
|
||||
if (dbform->datconnlimit >= 0 &&
|
||||
!am_superuser &&
|
||||
CountDBBackends(MyDatabaseId) > dbform->datconnlimit)
|
||||
CountDBConnections(MyDatabaseId) > dbform->datconnlimit)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
|
||||
errmsg("too many connections for database \"%s\"",
|
||||
|
Reference in New Issue
Block a user