当应用程序连接 PostgreSQL 数据库遇到“FATAL: sorry, too many clients already”错误时,表示数据库连接数已经到达服务器允许的最大值,无法建立新的连接。
原因分析
PostgreSQL 允许的最大客户端连接数由配置参数 max_connections ,默认值通常为 100。
那是不是意味着客户端一定可以创建 100 个并发连接呢?
并不是,因为 PostgreSQL 还有另外两个相关参数:
superuser_reserved_connections 参数代表了 PostgreSQL 数据库为超级用户保留的连接数,默认值为 3。
也就是说,当客户端连接数到达 max_connections - superuser_reserved_connections 时,只有超级用户才能继续创建新的连接。
reserved_connections 参数代表了 PostgreSQL 数据库为拥有 pg_use_reserved_connections 角色的用户保留的连接数,默认值为 0。这个参数是 PostgreSQL 16 新增参数。
当可用连接数大于 superuser_reserved_connections 并且小于等于 superuser_reserved_connections + reserved_connections 时,只有超级用户或者拥有 pg_use_reserved_connections 角色的用户才能继续创建新的连接。
总结一下,假设 max_connections 参数设置为 100,superuser_reserved_connections 参数设置为 3,reserved_connections 参数设置为 10。此时,客户端最多可以同时创建 100 个连接;当连接数到达 87 并且小于 97 时,只有超级用户和 pg_use_reserved_connections 角色用户可以继续创建连接;当连接数到达 97 时,只有超级用户可以继续创建连接。
解决方法
我们可以利用数据库为超级用户保留的连接登录数据库,然后查看当前服务器进程情况:
系统视图 pg_stat_activity 显示了所有后端进程的信息,其中 backend_type 字段取值为 client backend 的进程对应客户端连接。通过这个视图可以了解客户端的连接情况。
如果应用程序的确需要更多的数据库连接,可以修改上面介绍的 PostgreSQL 配置参数,这些参数的修改都需要重启服务。
如果应用程序并不需要这么多连接,而是由于代码问题导致连接泄露,例如创建了数据库连接后没有正确地释放,或者数据库连接池配置不当导致打开了过多连接。这种情况就需要调整应用端代码,确保正确管理了数据库连接。