引入PGBouncer后Rails ActiveRecord连接异常排查求助
问题排查求助
我们此前因RDS实例连接耗尽引入PGBouncer,但之后出现多种ActiveRecord连接异常——仅主/写实例通过PGBouncer连接时触发问题,读实例连接正常。怀疑是超时或连接数配置问题,寻求排查方案。
异常信息
ActiveRecord::StatementInvalid: PG::ConnectionBad: PQconsumeInput() server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request.
ActiveRecord::ConnectionNotEstablished: connection to server at "{db server IP}", port 5432 failed: server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing
ActiveRecord::StatementInvalid: PG::ConnectionBad: PQsocket() can't get socket descriptor
PGBouncer配置
我们运行了多个小型PGBouncer实例(因它是单进程单线程),后续计划调优。
[databases] production = our_connection_string [pgbouncer] max_client_conn = 500 pool_mode = transaction default_pool_size = 200 server_idle_timeout = 30 reserve_pool_size = 0
Rails数据库配置
default: &default adapter: postgis postgis_extension: true encoding: unicode pool: <%= ENV['DB_POOL'] || ENV['RAILS_MAX_THREADS'] || 5 %> idle_timeout: 300 checkout_timeout: 5 schema_search_path: public, tiger prepared_statements: false production: primary: <<: *default url: <%= ENV[DATABASE_URL] %> primary_replica: <<: *default url: <%= ENV[DATABASE_REPLICA_URL] %>
更新1
尝试将server_idle_timeout设为默认值600秒,问题未改善。
排查方案
1. 对齐超时配置
- Rails的
idle_timeout为300秒,需确保Rails连接池空闲超时 ≤ PGBouncer服务器空闲超时,避免PGBouncer先断开Rails仍持有的连接。建议将PGBouncer的server_idle_timeout设为310秒(比Rails超时大10秒)。 - 检查RDS侧的连接超时参数(如
tcp_keepalives_idle、tcp_keepalives_interval),避免RDS主动断开与PGBouncer的连接。
2. 调整连接池参数
- PGBouncer的
default_pool_size=200需不超过RDS的max_connections上限,同时结合Rails进程数+线程数计算总客户端连接需求,避免池大小不足或过载。 - 启用
reserve_pool_size,设为default_pool_size的10%-20%(如20),缓解高峰时段连接等待压力。
3. 排查连接状态
- 登录PGBouncer执行
SHOW POOLS;,查看wait_count、wait_time指标,若等待次数过多,说明default_pool_size不足。 - 执行
SHOW SERVERS;,检查是否存在服务器连接频繁断开/重连的情况,确认是否由RDS主动触发。
4. 优化Rails连接池
- 增大
checkout_timeout(如设为10),避免高峰时因获取连接超时触发异常。 - 确认全局未开启
prepared_statements(当前已设为false,符合PGBouncer transaction模式要求)。
5. 日志分析
- 开启PGBouncer详细日志:设置
log_connections=1、log_disconnections=1、log_pooler_errors=1,追踪连接断开的时间点与原因。 - 查看Rails生产日志,定位异常触发场景(如是否出现在长时间后台任务、批量操作期间)。
6. 检查部署与网络
- 多个PGBouncer实例需确保负载均衡策略均匀分配连接,避免单个实例过载。
- 确认PGBouncer与RDS之间的网络稳定,排查防火墙、NAT设备是否会主动断开空闲连接。
内容的提问来源于stack exchange,提问作者CWitty
相关产品推荐
相关产品推荐

