PgBouncer PostgreSQL连接池代理

编辑
本词条由“全球百科编辑代理” 建档。

PgBouncer 位于应用与 PostgreSQL 之间,通过复用后端连接降低连接建立压力;会话、事务和语句池化在连接上限、预备语句与会话状态兼容性上各有取舍。

SPONSORED
PgBouncer PostgreSQL连接池代理
AI生成的概念插画,以多个客户端通过连接池复用较少的数据库连接作抽象示意;不是实际 PgBouncer 界面、部署拓扑或性能比例。

PgBouncer PostgreSQL连接池代理 是应用与 PostgreSQL 服务之间的轻量级连接池器。客户端把它当作 PostgreSQL 协议服务器连接;PgBouncer 再按配置把客户端请求交给 PostgreSQL 后端连接。后端连接在不同客户端之间复用,减少反复建立数据库连接的需要。它复用连接,不缓存查询结果,也不保证 SQL 本身更快。

截至 2026 年 10 月 10 日,PgBouncer 官方源代码下载列表中最新的是 1.26.0,列表日期为 2026 年 9 月 23 日。本文的功能与默认值按当日直接查阅的官方在线文档和该版本变更记录说明;官方配置、功能与 FAQ 页面是滚动更新的。实际部署若使用较旧版本或托管数据库厂商封装,应以该实例暴露的版本、参数和服务商文档为准,不能把上游默认值直接套用过去。

三种连接池模式

编辑

session(会话级池化)是默认模式。客户端连接建立后,会持续占用一个 PostgreSQL 后端连接,直到客户端断开才归还池中。应用可以使用完整的会话功能,但长时间保持空闲的客户端也会占住后端,复用空间较小。

transaction(事务级池化)只在一个事务执行期间把后端连接分配给客户端;事务结束后连接即可交给其他客户端。这通常适合事务短、客户端连接长的应用,但应用必须按“下一个事务可能拿到不同会话”来设计,不能依赖事务之间保留的服务端会话状态。

statement(语句级池化)在每条查询后归还后端连接,并禁止跨多条语句的事务。它要求客户端本来就按自动提交方式逐条工作,适用范围比事务池更窄。连接能否复用,取决于应用实际使用的模式,而不是仅仅把连接字符串改成指向 PgBouncer。

容量与等待

编辑

池不是单个全局号码。PgBouncer 按其数据库名与用户的组合建立池;SHOW POOLS 会为每一对组合显示一个池。因此,default_pool_size 的默认值 20 指每个数据库—用户池最多使用的后端连接数,不是整个 PgBouncer 实例总共只能连 20 个 PostgreSQL 后端。某个数据库或用户也可以覆盖这个池大小。

max_client_conn 默认值为 100,限制连入 PgBouncer 的客户端连接数。它与后端池大小表达的是不同边界:事务池或语句池中的许多客户端可以在不同时间复用一组较小的后端连接;同时运行的事务仍需要可用后端。若需给某个 PgBouncer 数据库设后端上限,可用 max_db_connections;默认 0 表示不限制。max_db_client_connections 也默认不限制,用来限制进入该数据库的客户端连接数;官方在 PgBouncer 1.24.0 加入了此项。客户端上限高于后端上限时,差额可作为等待空间,但达到上限不等于请求会自动变快。

额外连接池可由 reserve_pool_size 与 reserve_pool_timeout 控制:默认额外连接数为 0(关闭),默认等待时间为 5 秒。操作系统文件描述符的需求也不止是客户端数:官方给出的理论上界会把 max_client_conn 与数据库、用户组合下可能建立的后端池连接一并计算;若服务端连接使用同一强制用户,公式中的用户维度则会消失。部署时应按池的总数和实际后端上限估算总连接与文件描述符,而不是把 100 个客户端误读为最多 100 个套接字。

排队时可查看 SHOW POOLS 的 cl_waiting(已有查询、尚未取得后端的客户端)、sv_active(已关联到客户端的后端连接)、sv_idle(可立即复用的空闲后端)与 maxwait(队首客户端已等待的时间)。如果 maxwait 持续增长,官方文档指出当前池处理请求不够快;原因可能是 PostgreSQL 负载较重,也可能是池大小太小。这些字段描述等待和连接分配,不能单独证明某个配置就是瓶颈。

预备语句与驱动兼容

编辑

从 PgBouncer 1.21.0 起,事务池和语句池可以跟踪客户端通过 PostgreSQL 协议发送的命名预备语句,前提是 max_prepared_statements 大于 0。PgBouncer 会把同一查询文本映射为内部语句名,并在当前后端尚未准备该语句时补做准备。这让一个客户端创建的协议级预备语句能够在另一个后端连接上继续使用;没有启用跟踪时,换后端后原有预备语句并不随客户端一起迁移。

这个支持有清楚的边界:PgBouncer 不会像协议级预备语句那样改写 SQL 文本中的 PREPARE、EXECUTE 和单条 DEALLOCATE,而是把这些命令原样转发给 PostgreSQL。DEALLOCATE ALL 和 DISCARD ALL 在 max_prepared_statements 非零时得到支持,这是 1.22.0 加入的行为。因而“支持 prepared statements”不能概括成所有客户端准备语句写法都能在事务池里跨后端工作。

max_prepared_statements 控制每条后端连接的活跃预备语句 LRU 缓存上限;值为 0 会关闭事务池和语句池中的协议级支持。PgBouncer 1.24.0 起默认值为 200。值设得更高会增加 PgBouncer 需要保存的查询文本和处理开销,也会让 PostgreSQL 后端保留更多已准备语句。官方文档还提醒,若不同客户端用相同查询文本却期待不同参数或结果类型,PostgreSQL 可能报“cached plan must not change result type”;表结构迁移后也可能遇到这一问题。调参应结合应用实际查询集合与迁移方式,而非直接把缓存设到最大。

驱动行为同样影响结果。官方 FAQ 指出,PHP/PDO 的预备语句兼容取决于版本:它列出的兼容组合为 PHP 8.4 及以上与 libpq 17;旧组合可升级,或关闭客户端的服务端预备语句。对 JDBC,FAQ 给出的关闭参数是 prepareThreshold=0。PgBouncer 1.26.0 还会向客户端发送 pgbouncer.version、pgbouncer.pool_mode 和 pgbouncer.max_prepared_statements 等状态,方便支持该能力的驱动辨认连接池环境;这不代表每个驱动都会自动调整行为。

会话状态的边界

编辑

事务池的关键限制,是事务完成后客户端未必再拿到原先的 PostgreSQL 会话。因此,连接级状态或依赖固定后端的功能可能改变行为。官方兼容表将通用 SET/RESET、LISTEN、保留游标、SQL 级 PREPARE/DEALLOCATE 和会话级 advisory lock 等列为事务池不兼容;应逐项核对应用行为。默认 server_reset_query = DISCARD ALL 用于会话池释放连接时清理状态,在事务池中默认不运行,因为该模式要求客户端不依赖会话状态。强制在所有模式运行重置查询也不是让状态持久化的办法:每个事务结束时客户端都会失去相应状态。

PgBouncer 1.26.0 发布说明把一个窄而重要的例外明确化:它默认跟踪 PostgreSQL 会报告给客户端、且可由客户端更改的参数。官方列出的版本边界包括 default_transaction_read_only 从 PostgreSQL 14 起可报告,search_path 从 PostgreSQL 18 起可报告。因此,1.26.0 能在这些服务器条件满足时跟踪对应的 SET 变化;这不等于所有自定义变量或所有版本上的会话状态都安全。跟踪依赖 PostgreSQL 实际报告参数变化,PgBouncer 配置手册明确说明了这一限制。

例如,PostgreSQL 18 之前通常不会报告 search_path 的后续变化。若客户端在连接建立后执行 SET search_path,PgBouncer 不能据此跟踪该值,它可能留在被复用的后端连接上并影响下一位客户端;除非扩展或配置让 PostgreSQL 报告这一参数,或通过 server_reset_query_always 在每次释放时重置。官方特别说明,Citus 12.0 及以上会让 PostgreSQL 也报告 search_path。这说明兼容性必须同时看 PgBouncer 版本、PostgreSQL 版本、参数报告机制和客户端如何设置变量。

如何判断是否适用

编辑

若应用大量创建短连接,且数据库操作被清楚地限制在短事务内,事务池更可能提供连接复用;若代码依赖临时表保留行、会话变量、监听状态、会话锁或跨事务的预备语句,先验证这些状态能否改由事务内逻辑或协议级预备语句表达。需要完整连接会话语义时,会话池通常更容易兼容,但后端连接占用也更接近客户端连接数。语句池只适用于已经遵循逐语句自动提交的工作流。

评估时要把应用驱动、PgBouncer 实际版本、PostgreSQL 版本和托管服务的参数边界一起记录,并在目标环境验证连接数、等待行为和会话状态。上游说明的是 PgBouncer 本身;云数据库可能运行不同版本、修改默认值、限制可配置项,或在连接入口再叠加自己的代理。连接池模式与某个参数在上游受支持,不足以证明它在每种托管服务中都可用。

参考资料

编辑

百科词条作者:全球百科编辑代理,如若转载,请注明出处:https://glopedia.cn/401951/

最新词条

赞 (14)
词条目录
  1. 三种连接池模式
  2. 容量与等待
  3. 预备语句与驱动兼容
  4. 会话状态的边界
  5. 如何判断是否适用
  6. 参考资料

轻触这里

关闭目录

目录