diff options
Diffstat (limited to 'src/backend/utils/init/postinit.c')
-rw-r--r-- | src/backend/utils/init/postinit.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 40f145e0ab1..2f07ca7a0e1 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -719,6 +719,7 @@ InitPostgres(const char *in_dbname, Oid dboid, bool am_superuser; char *fullpath; char dbname[NAMEDATALEN]; + int nfree = 0; elog(DEBUG3, "InitPostgres"); @@ -922,16 +923,30 @@ InitPostgres(const char *in_dbname, Oid dboid, } /* - * The last few connection slots are reserved for superusers. Replication - * connections are drawn from slots reserved with max_wal_senders and not - * limited by max_connections or superuser_reserved_connections. + * The last few connection slots are reserved for superusers and roles with + * privileges of pg_use_reserved_connections. Replication connections are + * drawn from slots reserved with max_wal_senders and are not limited by + * max_connections, superuser_reserved_connections, or + * reserved_connections. + * + * Note: At this point, the new backend has already claimed a proc struct, + * so we must check whether the number of free slots is strictly less than + * the reserved connection limits. */ if (!am_superuser && !am_walsender && - SuperuserReservedConnections > 0 && - !HaveNFreeProcs(SuperuserReservedConnections)) - ereport(FATAL, - (errcode(ERRCODE_TOO_MANY_CONNECTIONS), - errmsg("remaining connection slots are reserved for superusers"))); + (SuperuserReservedConnections + ReservedConnections) > 0 && + !HaveNFreeProcs(SuperuserReservedConnections + ReservedConnections, &nfree)) + { + if (nfree < SuperuserReservedConnections) + ereport(FATAL, + (errcode(ERRCODE_TOO_MANY_CONNECTIONS), + errmsg("remaining connection slots are reserved for superusers"))); + + if (!has_privs_of_role(GetUserId(), ROLE_PG_USE_RESERVED_CONNECTIONS)) + ereport(FATAL, + (errcode(ERRCODE_TOO_MANY_CONNECTIONS), + errmsg("remaining connection slots are reserved for roles with privileges of pg_use_reserved_connections"))); + } /* Check replication permissions needed for walsender processes. */ if (am_walsender) |