summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorAndrew Dunstan <andrew@dunslane.net>2017-02-01 17:52:35 -0500
committerAndrew Dunstan <andrew@dunslane.net>2017-02-01 18:02:43 -0500
commitf1169ab501ce90e035a7c6489013a1d4c250ac92 (patch)
tree561667bd01bdfb5184853b65bccf1da5e326c1be /src/backend
parentaedd554f84bb3cedb32e6e2a954a70537a4da6b9 (diff)
downloadpostgresql-f1169ab501ce90e035a7c6489013a1d4c250ac92.tar.gz
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.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/transam/twophase.c1
-rw-r--r--src/backend/storage/ipc/procarray.c34
-rw-r--r--src/backend/storage/lmgr/proc.c2
-rw-r--r--src/backend/utils/init/postinit.c2
4 files changed, 38 insertions, 1 deletions
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 5b72c1dcf5..6fde2bd8bf 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -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;
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 3f47b984ee..cd14667c16 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -2745,6 +2745,38 @@ CountDBBackends(Oid databaseid)
}
/*
+ * 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
*/
void
@@ -2803,6 +2835,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++;
}
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 1b836f7c0a..8f467bef50 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -370,6 +370,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 */
@@ -542,6 +543,7 @@ InitAuxiliaryProcess(void)
MyProc->backendId = InvalidBackendId;
MyProc->databaseId = InvalidOid;
MyProc->roleId = InvalidOid;
+ MyProc->isBackgroundWorker = IsBackgroundWorker;
MyPgXact->delayChkpt = false;
MyPgXact->vacuumFlags = 0;
MyProc->lwWaiting = false;
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 21fdc6df6b..4d0a2a7bed 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -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\"",