标准答案

  1. session pooling 在客户端连接整个生命周期绑定后端连接,兼容临时表、session GUC 和会话状态,但后端连接复用效率较低。
  2. transaction pooling 在事务结束后归还连接,适合短事务和无会话状态的服务,但临时表、SET、通知、游标和部分 prepared statement 需要逐项验证。
  3. statement pooling 在每条语句后归还连接,边界最严格,通常不适合多语句事务或依赖会话状态的应用。
  4. 事务池模式下客户端连接数可以远大于数据库后端连接数,但数据库有效并发仍受后端池大小和查询资源限制。
  5. 切换模式要用真实驱动和事务测试,覆盖异常回滚、连接断开、迁移、锁、通知和请求上下文清理,不能只压测平均吞吐。

题目解析

PgBouncer 不是透明的“更大连接池”,它改变了会话状态的生命周期。应用如果把 SET、临时表、prepared statement 或 advisory lock 当成长期连接属性,切换 transaction pooling 后可能出现隐蔽错误。

选择模式时先列出应用依赖的 session state,再决定需要兼容性还是连接复用效率。不能为了降低数据库连接数而牺牲事务正确性。

迁移验证应包含业务错误和数据一致性,不仅看 QPS;尤其要确认连接归还时事务已经结束、变量没有串到下一次请求。

常见误区

  • 误区:不改应用就直接启用 transaction pooling。改正:先审查临时对象、会话变量、prepared statement 和通知等依赖。
  • 误区:把客户端连接数当数据库后端连接数。改正:PgBouncer 可以复用后端连接,但后端池仍有真实上限。
  • 误区:只用吞吐压测验证池化模式。改正:还要测试事务失败、连接重置、状态清理和长请求。

作者信息