PostgreSQL :FATAL: remaining connection slots are reserved for non-re ...

打印 上一主题 下一主题

主题 2126|帖子 2126|积分 6378

以下是完整的 PostgreSQL 毗连数超限问题解决方案文档:
PostgreSQL 毗连数超限问题解决方案

一、错误原因分析

错误 FATAL: remaining connection slots are reserved for non-replication superuser connections 表示:


  • PostgreSQL 数据库的毗连数已到达 max_connections 限定。
  • 剩余毗连槽位仅保留给非复制超等用户(如 postgres),平常用户(如 idc)无法建立新毗连。
关键机制


  • max_connections:数据库允许的最大毗连数(默认值通常为 100)。
  • superuser_reserved_connections:为超等用户预留的毗连数(默认值为 3)。
  • 当平常用户毗连数到达 max_connections - superuser_reserved_connections 时,仅超等用户可建立新毗连。
二、检察毗连数与配置


  • 检察最大毗连数
    1. SHOW max_connections; -- 输出当前配置的最大连接数
    复制代码
  • 检察当前毗连数
    1. SELECT COUNT(*) FROM pg_stat_activity; -- 统计所有活跃连接数
    复制代码
  • 按数据库/用户/客户端地址分组统计
    1. SELECT
    2.   datname AS "数据库",
    3.   usename AS "用户",
    4.   client_addr AS "客户端地址",
    5.   COUNT(*) AS "连接数"
    6. FROM pg_stat_activity
    7. GROUP BY datname, usename, client_addr
    8. ORDER BY COUNT(*) DESC;
    复制代码
  • 检察特定用户的查询会话
    1. SELECT datname, usename, query
    2. FROM pg_stat_activity
    3. WHERE usename = '目标用户名'; -- 替换为实际用户名
    复制代码
三、排查毗连走漏(应用侧问题)


  • 查抄代码逻辑

    • 确保数据库毗连在使用后准确关闭(如 Java 中使用 finally 块):
      1. Connection conn = null;
      2. try {
      3.     conn = DriverManager.getConnection(url, username, password);
      4.     // 执行数据库操作
      5. } catch (SQLException e) {
      6.     // 异常处理
      7. } finally {
      8.     if (conn != null && !conn.isClosed()) {
      9.         conn.close(); // 确保连接关闭
      10.     }
      11. }
      复制代码

  • 引入毗连池

    • 使用毗连池(如 HikariCP、PGBouncer)管理毗连,避免无限定创建新毗连:
      1. <!-- HikariCP 配置示例 -->
      2. <dataSource>
      3.     <jdbcUrl>jdbc:postgresql://localhost:5432/mydb</jdbcUrl>
      4.     <username>idc</username>
      5.     <password>password</password>
      6.     <maximumPoolSize>50</maximumPoolSize> <!-- 限制最大连接数 -->
      7. </dataSource>
      复制代码

四、服务侧配置调整

1. 调整最大毗连数

步骤

  • 编辑配置文件
    1. vi /etc/postgresql/版本号/main/postgresql.conf
    复制代码

    • 找到 max_connections = 100,修改为:
      1. max_connections = 200  # 根据服务器内存调整(每连接约消耗 10MB+ 内存)
      复制代码

  • 重启数据库
    1. sudo systemctl restart postgresql
    复制代码
注意事项


  • 需根据服务器内存调整,公式参考:max_connections = 总内存 / 每毗连内存占用(如 8GB 内存发起不超过 500)。
  • 重启会中断所有毗连,发起在低峰期操纵。
2. 开释无效毗连(谨慎操纵)

超等用户权限执行
  1. -- 终止所有非活跃连接(谨慎操作,避免影响业务)
  2. SELECT pg_terminate_backend(pid)
  3. FROM pg_stat_activity
  4. WHERE state = 'idle' AND pid != pg_backend_pid();
复制代码
3. 使用毗连池工具(保举)

保举工具


  • PGBouncer:轻量级毗连池,适合高并发场景。
    1. # 安装(Ubuntu 示例)
    2. sudo apt-get install pgbouncer
    复制代码

    • 配置文件
      1. [databases]
      2. mydb = host=localhost port=5432 dbname=mydb user=idc password=password
      3. [pgbouncer]
      4. listen_port = 6432
      5. max_client_conn = 100  # 客户端最大连接数
      6. pool_size = 20         # 数据库后端连接池大小
      复制代码
    • 启动服务
      1. sudo systemctl start pgbouncer
      复制代码

五、长期优化发起


  • 监控毗连数
    1. -- 定期执行以下查询,监控连接数趋势
    2. SELECT
    3.   datname,
    4.   COUNT(*) AS "连接数",
    5.   NOW() AS "时间"
    6. FROM pg_stat_activity
    7. GROUP BY datname
    8. ORDER BY COUNT(*) DESC;
    复制代码
  • 限定用户毗连数
    1. -- 为特定用户设置连接上限
    2. ALTER ROLE idc WITH CONNECTION LIMIT 50;
    复制代码


  • 业务逻辑优化

    • 减少长事件,避免事件阻塞毗连。
    • 使用异步查询或批量操纵减少毗连占用。

通过以上步骤,可有用解决 PostgreSQL 毗连数超限问题,并建立长期监控机制防止复发。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

三尺非寒

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表