关于减少PgBouncer中auth_user占用的大量数据库连接的咨询
看起来你碰到的是PgBouncer里auth_user(也就是你的pgbouncer用户)占用了大量数据库连接的问题,而且这些连接大多是权限不足的认证查询导致的,占了近40%的连接资源,确实会挤压应用的连接槽位。咱们一步步来解决这个问题:
先搞清楚背后的原因
你当前用的是transaction池模式,同时开启了auth_query——每次客户端连接或者重新认证时,PgBouncer都会用auth_user去PostgreSQL查询用户的密码哈希来完成验证。如果这个认证查询的频率太高,或者auth_user的连接没被有效复用,就会堆积大量这类无意义的连接。
针对性的解决方案
1. 优先改用auth_file替代auth_query(最有效)
你配置里已经有auth_file了,但同时又开了auth_query——PgBouncer会先查本地的auth_file,找不到匹配的用户才会去数据库执行auth_query。如果能把所有需要通过PgBouncer连接的用户的密码哈希都同步到auth_file里,就可以直接注释掉auth_query这一行。
这样一来,PgBouncer完全不需要再用auth_user去数据库做认证查询,那些多余的连接自然就消失了。同步密码哈希的话,可以从pg_shadow视图导出,或者写个简单脚本定期同步PostgreSQL的用户密码到auth_file里。
2. 优化auth_query的连接复用(如果必须保留auth_query)
如果因为某些原因不能去掉auth_query,可以给auth_user的连接单独设置池化规则,避免它占用太多资源:
- 在
[databases]段添加一个专门给认证用的数据库条目,限制它的连接池大小:pgbouncer_auth = host=localhost port=1234 dbname=postgres user=pgbouncer pool_size=5 - 给
auth_user的连接池设置min_pool_size(比如设为2),减少频繁创建连接的开销,让PgBouncer保留几个空闲连接用于后续认证查询。 - 另外,确保你的
auth_query语句是高效的,比如给查询涉及的字段(比如pg_shadow.usename)建立索引,加快查询速度,减少连接占用的时间。
3. 调整池化模式和客户端连接习惯
你当前用的是transaction模式,虽然适合大多数场景,但如果客户端频繁断开重连,也会导致认证查询增多。可以检查客户端是否保持了长连接,避免频繁触发认证。另外,你可以把reserve_pool_size设为一个小值(比如5),避免连接池耗尽时频繁创建新连接。
4. 临时清理多余连接
如果现在需要立刻腾出连接槽位,可以通过PgBouncer的管理界面操作:
- 用
psql连接到PgBouncer的管理库:psql -p 1234 pgbouncer - 执行命令杀掉
auth_user的空闲连接:KILL user=pgbouncer; - 也可以先查看当前连接情况:
SHOW POOLS;和SHOW CLIENTS;,定位空闲的auth连接再精准清理。
验证效果
修改配置后记得重启PgBouncer,然后通过PostgreSQL的pg_stat_activity视图监控auth_user的连接数,看看占比是否下降。
备注:内容来源于stack exchange,提问作者tad

