Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1375274

Browse files
committed
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.
1 parent eb5e9d9 commit 1375274

File tree

8 files changed

+47
-3
lines changed

8 files changed

+47
-3
lines changed

doc/src/sgml/ref/create_database.sgml

+2-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ CREATE DATABASE <replaceable class="PARAMETER">name</replaceable>
258258
The <literal>CONNECTION LIMIT</> option is only enforced approximately;
259259
if two new sessions start at about the same time when just one
260260
connection <quote>slot</> remains for the database, it is possible that
261-
both will fail. Also, the limit is not enforced against superusers.
261+
both will fail. Also, the limit is not enforced against superusers or
262+
background worker processes.
262263
</para>
263264
</refsect1>
264265

doc/src/sgml/ref/create_role.sgml

+4-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,10 @@ CREATE ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replac
198198
<listitem>
199199
<para>
200200
If role can log in, this specifies how many concurrent connections
201-
the role can make. -1 (the default) means no limit.
201+
the role can make. -1 (the default) means no limit. Note that only
202+
normal connections are counted towards this limit. Neither prepared
203+
transactions nor background worker connections are counted towards
204+
this limit.
202205
</para>
203206
</listitem>
204207
</varlistentry>

src/backend/access/transam/twophase.c

+1
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
420420
proc->backendId = InvalidBackendId;
421421
proc->databaseId = databaseid;
422422
proc->roleId = owner;
423+
proc->isBackgroundWorker = false;
423424
proc->lwWaiting = false;
424425
proc->lwWaitMode = 0;
425426
proc->waitLock = NULL;

src/backend/storage/ipc/procarray.c

+34
Original file line numberDiff line numberDiff line change
@@ -2751,6 +2751,38 @@ CountDBBackends(Oid databaseid)
27512751
return count;
27522752
}
27532753

2754+
/*
2755+
* CountDBConnections --- counts database backends ignoring any background
2756+
* worker processes
2757+
*/
2758+
int
2759+
CountDBConnections(Oid databaseid)
2760+
{
2761+
ProcArrayStruct *arrayP = procArray;
2762+
int count = 0;
2763+
int index;
2764+
2765+
LWLockAcquire(ProcArrayLock, LW_SHARED);
2766+
2767+
for (index = 0; index < arrayP->numProcs; index++)
2768+
{
2769+
int pgprocno = arrayP->pgprocnos[index];
2770+
volatile PGPROC *proc = &allProcs[pgprocno];
2771+
2772+
if (proc->pid == 0)
2773+
continue; /* do not count prepared xacts */
2774+
if (proc->isBackgroundWorker)
2775+
continue; /* do not count background workers */
2776+
if (!OidIsValid(databaseid) ||
2777+
proc->databaseId == databaseid)
2778+
count++;
2779+
}
2780+
2781+
LWLockRelease(ProcArrayLock);
2782+
2783+
return count;
2784+
}
2785+
27542786
/*
27552787
* CancelDBBackends --- cancel backends that are using specified database
27562788
*/
@@ -2810,6 +2842,8 @@ CountUserBackends(Oid roleid)
28102842

28112843
if (proc->pid == 0)
28122844
continue; /* do not count prepared xacts */
2845+
if (proc->isBackgroundWorker)
2846+
continue; /* do not count background workers */
28132847
if (proc->roleId == roleid)
28142848
count++;
28152849
}

src/backend/storage/lmgr/proc.c

+2
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ InitProcess(void)
372372
MyProc->backendId = InvalidBackendId;
373373
MyProc->databaseId = InvalidOid;
374374
MyProc->roleId = InvalidOid;
375+
MyProc->isBackgroundWorker = IsBackgroundWorker;
375376
MyPgXact->delayChkpt = false;
376377
MyPgXact->vacuumFlags = 0;
377378
/* NB -- autovac launcher intentionally does not set IS_AUTOVACUUM */
@@ -544,6 +545,7 @@ InitAuxiliaryProcess(void)
544545
MyProc->backendId = InvalidBackendId;
545546
MyProc->databaseId = InvalidOid;
546547
MyProc->roleId = InvalidOid;
548+
MyProc->isBackgroundWorker = IsBackgroundWorker;
547549
MyPgXact->delayChkpt = false;
548550
MyPgXact->vacuumFlags = 0;
549551
MyProc->lwWaiting = false;

src/backend/utils/init/postinit.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ CheckMyDatabase(const char *name, bool am_superuser)
350350
*/
351351
if (dbform->datconnlimit >= 0 &&
352352
!am_superuser &&
353-
CountDBBackends(MyDatabaseId) > dbform->datconnlimit)
353+
CountDBConnections(MyDatabaseId) > dbform->datconnlimit)
354354
ereport(FATAL,
355355
(errcode(ERRCODE_TOO_MANY_CONNECTIONS),
356356
errmsg("too many connections for database \"%s\"",

src/include/storage/proc.h

+2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ struct PGPROC
102102
Oid databaseId; /* OID of database this backend is using */
103103
Oid roleId; /* OID of role using this backend */
104104

105+
bool isBackgroundWorker; /* true if background worker. */
106+
105107
/*
106108
* While in hot standby mode, shows that a conflict signal has been sent
107109
* for the current transaction. Set/cleared while holding ProcArrayLock,

src/include/storage/procarray.h

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ extern pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReaso
7373

7474
extern bool MinimumActiveBackends(int min);
7575
extern int CountDBBackends(Oid databaseid);
76+
extern int CountDBConnections(Oid databaseid);
7677
extern void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending);
7778
extern int CountUserBackends(Oid roleid);
7879
extern bool CountOtherDBBackends(Oid databaseId,

0 commit comments

Comments
 (0)