标准答案
- session pooling 在客户端连接整个生命周期绑定后端连接,兼容临时表、session GUC 和会话状态,但后端连接复用效率较低。
- transaction pooling 在事务结束后归还连接,适合短事务和无会话状态的服务,但临时表、SET、通知、游标和部分 prepared statement 需要逐项验证。
- statement pooling 在每条语句后归还连接,边界最严格,通常不适合多语句事务或依赖会话状态的应用。
- 事务池模式下客户端连接数可以远大于数据库后端连接数,但数据库有效并发仍受后端池大小和查询资源限制。
- 切换模式要用真实驱动和事务测试,覆盖异常回滚、连接断开、迁移、锁、通知和请求上下文清理,不能只压测平均吞吐。
题目解析
PgBouncer 不是透明的“更大连接池”,它改变了会话状态的生命周期。应用如果把 SET、临时表、prepared statement 或 advisory lock 当成长期连接属性,切换 transaction pooling 后可能出现隐蔽错误。
选择模式时先列出应用依赖的 session state,再决定需要兼容性还是连接复用效率。不能为了降低数据库连接数而牺牲事务正确性。
迁移验证应包含业务错误和数据一致性,不仅看 QPS;尤其要确认连接归还时事务已经结束、变量没有串到下一次请求。
常见误区
- 误区:不改应用就直接启用 transaction pooling。改正:先审查临时对象、会话变量、prepared statement 和通知等依赖。
- 误区:把客户端连接数当数据库后端连接数。改正:PgBouncer 可以复用后端连接,但后端池仍有真实上限。
- 误区:只用吞吐压测验证池化模式。改正:还要测试事务失败、连接重置、状态清理和长请求。