PgBouncer 1.26.1 配置参数详解

PgBouncer 1.26.1 配置参数全量实测:SHOW CONFIG 98 参数总览、[databases]/[pgbouncer] 段核心参数逐项验证、session/transaction/statement 三池化模式差异实测、RELOAD 在线生效闭环与两套生产配置模板。

PgBouncerPostgreSQL数据库2026/10/20

PgBouncer 1.26.1 配置参数详解

目标:逐项讲清 PgBouncer 1.26.1 配置文件(pgbouncer.ini)的 [databases] 与 [pgbouncer] 两段核心参数,并以真实环境实测验证参数行为——包括三种池化模式差异、RELOAD 在线生效、连接上限拒绝、空闲连接回收等。文中全部命令与回显均在「Ubuntu 22.04.5 LTS + PgBouncer 1.26.1 + PostgreSQL 18.6 后端」环境实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(pgb-server 10.89.56.3 作为 PgBouncer 服务器,pg18-server 10.89.56.2 作为 PostgreSQL 服务器)
  • 系统架构:x86_64
  • PgBouncer:1.26.1(源码编译安装于 /usr/local,--with-systemd;pgbouncer -V 回显:libevent 2.1.12-stable / adns: evdns2 / tls: OpenSSL 3.0.2 / systemd: yes)
  • PostgreSQL:18.6(后端,密码认证 scram-sha-256,业务库 appdb、账号 appuser,密码 q1w2e3r4)
  • psql 客户端:psql (PostgreSQL) 14.24 (Ubuntu 14.24-0ubuntu0.22.04.1)
  • 配置文件:/etc/pgbouncer/pgbouncer.ini、/etc/pgbouncer/userlist.txt
  • 日志/运行目录:/var/log/pgbouncer/、/var/run/pgbouncer/
  • 管理控制台入口:psql -h 127.0.0.1 -p 6432 -U postgres pgbouncer(admin_users 中的用户连接虚拟库 pgbouncer)

二、前置条件

  1. 已按 《Ubuntu 22.04 安装 PgBouncer 1.26.1 指南》第八章完成基础配置,PgBouncer 处于运行状态:
systemctl is-active pgbouncer

实测回显:

active
  1. 后端 PostgreSQL 可连通(业务库 appdb 已存在):
PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U appuser appdb -c "SELECT 1 AS ok;"

实测回显:

 ok
----
  1
(1 row)
  1. 管理控制台可用(本文大量使用):
PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U postgres pgbouncer -c "SHOW VERSION;"

实测回显:

     version
------------------
 PgBouncer 1.26.1
(1 row)

三、参数查看与修改方式

3.1 配置文件结构

pgbouncer.ini 由两类段组成(来源:pgbouncer.org/config.html,查询日期 2026-10-20):

  • [databases]:逻辑库名到后端连接信息的映射。行格式为 逻辑库名 = host=... port=... dbname=... [附加参数];连接串里带 * 时表示"未显式映射的库名全部按此规则透传"。
  • [pgbouncer]:全局运行参数。每个参数一行 key = value;多数参数支持运行时修改(changeable=yes),改完 ini 后在管理控制台执行 RELOAD 即可生效,无需重启。

3.2 SHOW CONFIG:在线查看全部参数

管理控制台的 SHOW CONFIG 一次列出全部参数的当前值、默认值与是否可在线修改:

PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U postgres pgbouncer -c "SHOW CONFIG;" | head -12

实测回显(输出节选,全表 98 行参数):

             key             |                                                             value                                                              |                                                            default                                                             | changeable
-----------------------------+--------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------+------------
 admin_users                 | postgres                                                                                                                       |                                                                                                                                | yes
 application_name_add_host   | 0                                                                                                                              | 0                                                                                                                              | yes
 auth_dbname                 |                                                                                                                                |                                                                                                                                | yes
 auth_file                   | /etc/pgbouncer/userlist.txt                                                                                                    |                                                                                                                                | yes
 auth_hba_file               |                                                                                                                                |                                                                                                                                | yes
 auth_ident_file             |                                                                                                                                |                                                                                                                                | yes
 auth_ldap_options           |                                                                                                                                |                                                                                                                                | yes
 auth_query                  | SELECT rolname, CASE WHEN rolvaliduntil < now() THEN NULL ELSE rolpassword END FROM pg_authid WHERE rolname=$1 AND rolcanlogin | SELECT rolname, CASE WHEN rolvaliduntil < now() THEN NULL ELSE rolpassword END FROM pg_authid WHERE rolname=$1 AND rolcanlogin | yes
 auth_type                   | scram-sha-256                                                                                                                  | md5                                                                                                                            | yes
 auth_user                   |                                                                                                                                |                                                                                                                                | yes

要点解读:changeable 列为 no 的参数(如 listen_addr、listen_port、pidfile、unix_socket_dir、conffile、pkt_buf 等)只在进程启动时读取一次,修改后必须重启进程;为 yes 的参数修改 ini 后 RELOAD 即时生效。

3.3 RELOAD:在线生效与验证

以 server_idle_timeout 为例演示"改 ini → RELOAD → SHOW CONFIG 确认"的完整闭环。先在 ini 中临时追加(放在 [pgbouncer] 段内任意位置):

server_idle_timeout = 5

执行 RELOAD 并确认新值:

PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U postgres pgbouncer -c "RELOAD;"
PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U postgres pgbouncer -c "SHOW CONFIG;" | grep server_idle_timeout

实测回显:

RELOAD
 server_idle_timeout         | 5                                                                                                                              | 600                                                                                                                            | yes

value 列已变为 5,默认值 600 作为参照保留展示。验证完成后把该行从 ini 删除并再次 RELOAD 恢复默认。

四、参数总览

1.26.1 全部 98 个参数按职能分为九类,各类代表参数如下(完整清单可随时 SHOW CONFIG 获取):

分类代表参数说明
监听与并发listen_addr、listen_port、max_client_conn、listen_backlog、so_reuseport进程入口与客户端总闸
认证与凭据auth_type、auth_file、auth_user、auth_query、auth_hba_file、auth_ldap_options、scram_iterations代理层认证体系
池容量default_pool_size、min_pool_size、reserve_pool_size、max_db_connections、max_user_connections、max_db_client_connections、max_user_client_connections各维度连接数上限
池化行为pool_mode、server_reset_query、server_check_query、server_check_delay、server_round_robin、query_wait_timeout、query_wait_notify、idle_transaction_timeout、transaction_timeout复用与排队行为
连接生命周期server_lifetime、server_idle_timeout、server_connect_timeout、server_login_retry、client_login_timeout、client_idle_timeout、cancel_wait_timeout、autodb_idle_timeout、pool_idle_timeout各类超时
日志与统计logfile、syslog、log_connections、log_disconnections、log_pooler_errors、log_stats、stats_period、verbose观测面
TLSclient_tls_sslmode、client_tls_ca_file、client_tls_cert_file、client_tls_key_file、server_tls_sslmode、server_tls_protocols、client_tls13_ciphers、server_tls13_ciphers双向 TLS
DNSdns_max_ttl、dns_nxdomain_ttl、dns_zone_check_period、resolv_conf异步解析调优
底层与杂项pkt_buf、max_packet_size、sbuf_loopcnt、tcp_keepalive 系列、unix_socket_dir、track_extra_parameters、login_notify_message协议缓冲与系统参数

💡 技术拓展:PgBouncer 的连接数限制是四层漏斗模型,配置时应从外到内协同考虑——

层参数默认值管的是什么
客户端总量max_client_conn100连到 PgBouncer 的 TCP 连接总数(含排队)
每库客户端max_db_client_connections0(不限)单个逻辑库上的客户端总数
每用户客户端max_user_client_connections0(不限)单个数据库用户上的客户端总数
后端物理连接pool_size / max_db_connections / max_user_connections20 / 0 / 0真正打到 PostgreSQL 的连接数

实际生产通常:调大 max_client_conn(如 2000~10000)作为前端总闸,用 pool_size 系参数控制后端物理连接数——这正是连接池的核心价值。

五、[databases] 段参数详解

5.1 基本映射与通配符

本文实测 ini 的 [databases] 段:

[databases]
appdb = host=10.89.56.2 port=5432 dbname=appdb
admindb = host=10.89.56.2 port=5432 dbname=admindb

客户端用 psql ... appdb 连接"逻辑库 appdb",PgBouncer 实际连接 10.89.56.2:5432 上的 appdb 库。SHOW DATABASES 可看到映射结果(实测回显):

   name    |    host     | port | database  | force_user | pool_size | min_pool_size | reserve_pool_size | server_lifetime | pool_mode | load_balance_hosts | max_connections | current_connections | max_client_connections | current_client_connections | paused | disabled
-----------+-------------+------+-----------+------------+-----------+---------------+-------------------+-----------------+-----------+--------------------+-----------------+---------------------+------------------------+----------------------------+--------+----------
 admindb   | pg18-server | 5432 | admindb   |            |        20 |             0 |                 2 |            3600 |           |                    |              50 |                   0 |                      0 |                          0 |      0 |        0
 appdb     | pg18-server | 5432 | appdb     |            |        20 |             0 |                 2 |            3600 |           |                    |              50 |                   0 |                      0 |                          0 |      0 |        0
 pgbouncer |             | 6432 | pgbouncer | pgbouncer  |         2 |             0 |                 0 |            3600 | statement |                    |              50 |                   0 |                      0 |                          1 |      0 |        0
(3 rows)

(pool_mode 列为空表示跟随全局参数;虚拟库 pgbouncer 本身固定 statement 模式、force_user=pgbouncer,这是管理控制台的固定形态。)

5.2 映射行可用参数

每个 [databases] 映射行可覆盖的全局参数(来源:pgbouncer.org/config.html database 段说明,查询日期 2026-10-20):host、port、dbname、user(force_user)、password、client_encoding、datestyle、timezone、pool_size、min_pool_size、reserve_pool_size、max_connections、server_lifetime、connect_query、pool_mode、load_balance_hosts。

5.3 实测:per-db pool_mode 覆盖

只把 appdb 覆盖为 statement 模式,全局仍是 session——验证"按库差异化池化"。修改映射行:

appdb = host=10.89.56.2 port=5432 dbname=appdb pool_mode=statement
PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U postgres pgbouncer -c "RELOAD;"

连 appdb 发起显式事务(实测回显):

PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U appuser appdb -c "BEGIN"
FATAL:  transaction blocks not allowed in statement pooling mode

连 admindb(未覆盖,全局 session 生效)发起事务(实测回显):

PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U postgres admindb -c "BEGIN; SELECT 7 AS tx_ok; COMMIT;"
COMMIT

结论:per-db 参数只影响该库的池,其他库不受影响——同一 PgBouncer 实例可以为"老应用用 session、报表批处理用 transaction、单语句工具用 statement"各配各的。验证后把 pool_mode=statement 从映射行删除并 RELOAD。

六、[pgbouncer] 核心参数分类详解

6.1 监听与并发类

参数默认值说明
listen_addrlocalhost监听 IP,多个逗号分隔;0.0.0.0 全网卡。启动期参数
listen_port6432监听端口。启动期参数
max_client_conn100客户端连接总数上限,超限直接拒绝
listen_backlog128TCP backlog。启动期参数
so_reuseport0多实例监听同一端口做内核负载均衡(1.26 官方推荐的滚动重启基础)

实测:max_client_conn 超限拒绝。 临时改为 1 并 RELOAD,先占住一个连接,第二个连接被拒:

PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U appuser appdb -c "SELECT 2;"

实测回显:

psql: error: connection to server at "127.0.0.1", port 6432 failed: FATAL:  no more connections allowed (max_client_conn)

验证后改回 100 并 RELOAD。注意:admin_users 的管理控制台连接不受该限制影响(实测 max_client_conn=1 时管理连接仍可建立,便于容量告急时进控制台排障)。

6.2 认证类

参数默认值说明
auth_typemd5认证方式:trust/any/md5/scram-sha-256/cert/hba/pam/ldap
auth_file(空)userlist.txt 路径,格式 "user" "password或secret"
auth_user(空)auth_query 使用的只读账号(需能查 pg_authid)
auth_querySELECT rolname, ... FROM pg_authid WHERE rolname=$1 AND rolcanlogin从后端取密码哈希的查询
auth_hba_file(空)pg_hba.conf 风格规则文件(auth_type=hba 时用)
scram_iterations4096生成 SCRAM secret 的迭代次数(1.25.0 新增,可换认证速度)
auth_ldap_options(空)LDAP 认证选项(1.25.0+,编译期 --with-ldap)

本文实测采用 auth_type = scram-sha-256 + auth_file 明文口令形态:PgBouncer 用 userlist.txt 中的明文与客户端完成 SCRAM 握手,再向后端发起独立的 SCRAM 认证。实测链路见第二章第 2 条回显(SELECT 1 成功)。

⚠️ 注意:auth_type=md5 时若后端用户是 SCRAM 存储(PG 14+ 默认),md5 认证链路会失败;PG 18 后端统一用 scram-sha-256 是最省心的选择。

6.3 池容量类

参数默认值说明
default_pool_size20每个「库×用户」池的常规物理连接数
min_pool_size0池保底连接数(有客户端连着时才生效)
reserve_pool_size0突发备用连接数,常规池满且等待超 reserve_pool_timeout 秒后启用
reserve_pool_timeout5触发备用池的等待秒数
max_db_connections0(不限)单个后端数据库的物理连接总数上限(跨池合计)
max_user_connections0(不限)单个用户的物理连接总数上限
max_db_client_connections0单库客户端连接上限
max_user_client_connections0单用户客户端连接上限
max_prepared_statements200协议级 prepared statement 跟踪缓存上限(0 关闭)

实测:min_pool_size 预建连接。 设 min_pool_size = 5 时,客户端一登录(session 模式),SHOW POOLS 立即出现(实测回显):

 appdb     | appuser   |         1 |          0 |                    0 |                     0 |         0 |                0 |                 0 |       5 |       0 |         0 |        0 |       0 |          0 | session   |

即池按保底值预建了 5 条空闲物理连接(sv_idle=5),能消除冷池首查询的建连延迟;代价是后端常驻更多空连接。验证后把 min_pool_size 从 ini 删除并 RELOAD 恢复 0。

6.4 池化行为类(核心)

参数默认值说明
pool_modesession池化模式:session/transaction/statement(差异实测见第七章)
server_reset_queryDISCARD ALL连接归还后端的清理语句(transaction/statement 模式默认不执行,由参数跟踪机制替代)
server_reset_query_always01 时任何模式都执行 reset_query
server_check_query(空)探活查询,1.25.0 起默认发空查询代替 SELECT 1
server_check_delay30空闲连接探活周期
server_round_robin01 时多后端主机间轮询分配
query_wait_timeout120客户端排队等待物理连接的超时(1.26.0 起可按库/用户覆盖)
query_wait_notify5排队超过该秒数向客户端发 NOTICE(0 关闭)
idle_transaction_timeout0事务池模式下客户端 idle-in-transaction 超时秒数
transaction_timeout0单个事务最长允许时长(1.25.0 新增)
disable_pqexec01 时禁用简单查询协议(防 SQL 注入面)

实测:query_wait_timeout 场景的可观测面。 PAUSE 期间新查询排队,SHOW POOLS 的 cl_waiting 与 maxwait 直观可见(实测回显,PAUSE appdb 后 2 秒快照):

 appdb     | appuser   |         0 |          1 |                    0 |                     0 |         0 |                0 |                 0 |       0 |       0 |         0 |        0 |       2 |       1979 | session   |

maxwait=2(秒)、maxwait_us=1979(微秒)——这正是容量规划时判断"池是否过小"的关键指标:生产上若 maxwait 长期非零,应优先扩 pool_size 或排查慢事务,而不是无脑调大 query_wait_timeout。

6.5 连接生命周期类

参数默认值说明
server_lifetime3600物理连接最长存活秒数,到期后等事务结束即关闭
server_idle_timeout600池内空闲物理连接的存活秒数
server_connect_timeout15连后端超时
server_login_retry15后端连不上时的重试间隔
client_login_timeout60客户端完成登录的超时
client_idle_timeout0(不限)客户端空闲连接超时(仅登录后空闲)
cancel_wait_timeout10取消请求等待秒数
autodb_idle_timeout3600无人使用的"通配映射库"池的回收秒数
pool_idle_timeout0(不限)整个池闲置多久后被整体清理(1.26.0 新增;清理会丢失池统计)
suspend_timeout10SUSPEND 等待收尾秒数(1.26.0 起该机制随 takeover 移除而仅余兼容语义)

实测:server_idle_timeout=5 的回收行为。 改为 5 秒并 RELOAD 后,先制造一条空闲物理连接,1 秒时 sv_idle=1;7 秒后再查已归零(实测回显):

-- 1 秒后 --
 appdb     | appuser   |         0 |          0 |                    0 |                     0 |         0 |                0 |                 0 |       1 |       0 |         0 |        0 |       0 |          0 | session   |
-- 7 秒后 --
 appdb     | appuser   |         0 |          0 |                    0 |                     0 |         0 |                0 |                 0 |       0 |       0 |         0 |        0 |       0 |          0 | session   |

结论:空闲超时回收真实生效。生产取值应大于"应用两次请求的典型间隔",否则物理连接反复重建,反而放大后端负担。

6.6 日志与统计类

参数默认值说明
logfile(空,仅 stderr)日志文件路径
log_connections / log_disconnections1建连/断连留痕
log_pooler_errors1池化错误(排队超时、登录失败等)留痕
log_stats1按 stats_period 周期输出统计摘要
stats_period60统计周期秒数(SHOW STATS 的 avg_* 以此为窗口)
verbose0运行时日志详细度,可 SET verbose=1 在线调整

实测 SET verbose = 1 后控制台返回 SET verbose=1、SET verbose = 0 恢复——排障时可临时打开而不必改 ini 重载。

6.7 TLS 类

参数默认值说明
client_tls_sslmodedisable客户端侧 TLS(disable/allow/require/verify-ca/verify-full)
client_tls_ca_file / client_tls_cert_file / client_tls_key_file(空)客户端侧证书链
client_tls_protocolssecure客户端侧协议白名单(默认 TLSv1.2+)
client_tls13_ciphers / server_tls13_ciphers(空)TLS 1.3 套件选择(1.25.0 新增)
server_tls_sslmodeprefer后端侧 TLS
server_tls_ca_file / server_tls_cert_file / server_tls_key_file(空)后端侧证书链
server_tls_protocolssecure后端侧协议白名单

⚠️ 注意:client_tls_sslmode 默认 disable 意味着"应用 → PgBouncer"这一跳默认明文,跨网段部署必须显式启用并配 verify-full;server_tls_sslmode 默认 prefer 表示后端可用 TLS 时自动加密。1.25.0 起客户端侧还支持 PG 17 的 direct TLS 快速握手。

6.8 DNS 类

参数默认值说明
dns_max_ttl15域名解析缓存秒数
dns_nxdomain_ttl15NXDOMAIN 缓存秒数
dns_zone_check_period0SOA 序号周期检查(0 关闭),变化即重解析
resolv_conf(空)指定自定义 resolv.conf

实测 SHOW DNS_HOSTS 可见解析缓存(回显:hostname pg18-server / ttl 0 / addrs 10.89.56.2:0)——后端按主机名连接时,DNS 故障切换场景(如 RDS 漂移)靠这几个参数控制感知速度。

6.9 底层与杂项类

参数默认值说明
pkt_buf4096包缓冲大小(启动期参数)
max_packet_size2147483647单包上限;默认值不受 CVE-2026-107348 影响
sbuf_loopcnt5单次事件循环内最多转发包数(大查询吞吐相关)
track_extra_parameters(1.26 显示为空)额外跟踪的连接参数;1.26.0 起服务端上报参数默认全跟踪,无需手工追加
login_notify_message(空)登录后向客户端发送的 NOTICE 文案(1.26.0 新增,用于明示"你连的是 PgBouncer")
application_name_add_host01 时把客户端地址追加到 application_name,便于后端 pg_stat_activity 区分来源
tcp_keepalive / tcp_keepidle / tcp_keepintvl / tcp_keepcnt1 / 0 / 0 / 0内核级 TCP 保活
tcp_user_timeout0TCP 用户超时毫秒数(0 用内核默认)
unix_socket_dir/tmpUnix socket 目录(启动期参数)
unix_socket_mode0777Unix socket 权限(启动期参数)

实测:1.26 参数跟踪默认开启的证据。 同一配置在 1.25.2 下 SHOW CONFIG 显示 track_extra_parameters | IntervalStyle(默认追加 IntervalStyle);升级 1.26.1 后同参数默认值变为空——因为 PG 服务端上报的全部参数(含 PG 18 的 search_path、PG 14+ 的 default_transaction_read_only)已默认跟踪(来源:GitHub Releases 1.26.0 Features,实测对照 1.25.2 与 1.26.1 的 SHOW CONFIG,查询日期 2026-10-20)。

七、池化模式差异实测(session / transaction / statement)

本章是池化行为类参数的核心实验:同一套环境,仅切换 pool_mode,观察 SHOW POOLS 中各状态列的变化。实验脚本形态:后台保持一个客户端连接(sleep 管道保持 stdin),期间从管理控制台抓 SHOW POOLS 快照。

7.1 session 模式:客户端在线即独占

pool_mode=session(默认)时,客户端只要连着(哪怕不发任何 SQL),就持有一条物理连接:

 appdb     | appuser   |         1 |          0 |                    0 |                     0 |         0 |                0 |                 0 |       1 |       0 |         0 |        0 |       0 |          0 | session   |

解读:cl_active=1(一个客户端在线),sv_idle=1(一条物理连接已分配给它)。session 模式下"客户端数 ≈ 物理连接数",池化收益最低但兼容性最好。

7.2 transaction 模式:事务外归还

pool_mode=transaction 时,同样"客户端在线但空闲在事务外"的快照:

 appdb     | appuser   |         2 |          0 |                    0 |                     0 |         0 |                0 |                 0 |       1 |       0 |         0 |        0 |       0 |          0 | transaction |

解读:cl_active=2(两个客户端在线)而 sv_active=0——没有任何一条物理连接被占用,连接已在事务结束时全部归还池中。事务期间再抓快照(客户端执行 BEGIN; SELECT pg_sleep(12); COMMIT;):

 appdb     | appuser   |         2 |          0 |                    0 |                     0 |         1 |                0 |                 0 |       0 |       4 |         0 |        0 |       0 |          0 | transaction |

sv_active=1:只有事务真正运行的那 12 秒占住物理连接。这就是 transaction 模式"数百客户端 × 少量后端连接"的机制基础。

transaction 模式下扩展协议的 prepared statement 也能安全使用(1.21+ 的自动跟踪)。实测:transaction 模式下 PREPARE 后跨语句 EXECUTE(psql 两次 -c,物理连接可能已复用他人):

PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U appuser appdb -c "PREPARE hello(int) AS SELECT \$1*10; EXECUTE hello(5);"

实测回显:

 ?column?
----------
       50
(1 row)

PgBouncer 在需要时自动向新物理连接重放 PREPARE,应用无感(依赖 max_prepared_statements 跟踪,默认 200)。

7.3 statement 模式:单语句即归还、禁止事务

pool_mode=statement 时,物理连接在每条语句结束后立即归还。单语句正常(实测回显):

 ok
----
  1
(1 row)

显式事务直接被拒(实测回显):

PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 6432 -U appuser appdb -c "BEGIN"
FATAL:  transaction blocks not allowed in statement pooling mode

该报错是 statement 模式的标志性边界:它强制 autocommit 语义,适合"单条 SELECT/INSERT 为主"的工具类流量(如监控探针、简单看板),不适合任何事务型应用。

7.4 三模式对比总结

观测项sessiontransactionstatement
客户端空闲时占物理连接占(sv_used/sv_idle 分配给它)不占(sv_active=0)不占
事务期间占整个会话时长仅事务运行期占不支持事务
复用比(客户端:物理)≈1:1数百:1 可达最高
BEGIN/COMMIT正常正常FATAL 拒绝
SET/游标/LISTEN 跨语句安全需依赖参数跟踪(1.26 默认跟踪服务端参数)不适用

选型建议:生产默认 transaction;老应用会话状态重且无法改造时用 session;探针/单语句工具可 statement。

八、生产配置模板

模板一:OLTP 应用池(16GB 内存 PgBouncer 独立小机,后端 PG 18,数百微服务实例)

[databases]
appdb = host=10.89.56.2 port=5432 dbname=appdb pool_mode=transaction

[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt
admin_users = postgres
stats_users = postgres
pool_mode = transaction
max_client_conn = 5000
default_pool_size = 50
min_pool_size = 10
reserve_pool_size = 10
reserve_pool_timeout = 3
max_db_connections = 200
server_lifetime = 3600
server_idle_timeout = 300
query_wait_timeout = 30
idle_transaction_timeout = 60
max_prepared_statements = 200
log_connections = 0
log_disconnections = 0
log_pooler_errors = 1
log_stats = 1
stats_period = 60
logfile = /var/log/pgbouncer/pgbouncer.log
pidfile = /var/run/pgbouncer/pgbouncer.pid
unix_socket_dir = /var/run/pgbouncer

适用说明:NVMe SSD 任意容量即可(PgBouncer 几乎无磁盘 IO);内存 512MB 起步绰绰有余;核心思路是"前端总闸 5000,后端物理 200 封顶",等待超时 30 秒快速失败,idle 事务 60 秒强制回收防 vacuum 阻塞。

模板二:保守会话池(老应用强会话依赖,2GB 内存小机)

[databases]
appdb = host=10.89.56.2 port=5432 dbname=appdb pool_mode=session

[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = scram-sha-256
auth_file = /etc/pgbouncer/userlist.txt
admin_users = postgres
pool_mode = session
max_client_conn = 300
default_pool_size = 100
server_lifetime = 7200
server_idle_timeout = 600
client_idle_timeout = 1800
log_pooler_errors = 1
logfile = /var/log/pgbouncer/pgbouncer.log
pidfile = /var/run/pgbouncer/pgbouncer.pid
unix_socket_dir = /var/run/pgbouncer

适用说明:session 模式复用比≈1:1,max_client_conn 不可虚高(否则失去保护意义);client_idle_timeout 1800 秒清理遗忘的长连接;该形态对后端连接数要求 = 客户端峰值,本质是"限流闸"而非"复用池"。

九、常见问题(FAQ)

Q1:改了 pgbouncer.ini 不生效? 分两类:changeable=yes 的参数需在控制台执行 RELOAD(或 kill -HUP);changeable=no 的参数(listen_addr/listen_port/pidfile/unix_socket_dir/pkt_buf 等)必须重启进程(systemctl restart pgbouncer)。SHOW CONFIG 的 changeable 列是权威依据。

Q2:RELOAD 后已存在的连接会断吗? 不会。RELOAD 只影响新连接的分配与池参数,活动事务不受影响;server_lifetime 缩短等生效也是"温和回收"(事务结束后关闭),不会掐断业务。

Q3:transaction 模式下 SET application_name / search_path 会互相污染吗? 1.26.0 起 PgBouncer 默认跟踪 PostgreSQL 上报的全部连接参数,客户端 SET 后连接归还/再分配时会正确恢复,不再污染下一个客户端(1.25 及以前需要把参数加进 track_extra_parameters 或依赖应用侧每次 SET)。特殊参数仍可通过 track_extra_parameters 显式追加。

Q4:SHOW POOLS 里 maxwait 一直大于 0 怎么办? 说明有客户端在排队等物理连接。先看 sv_active 是否长期顶满 pool_size:是则扩池(default_pool_size)或优化慢事务;偶尔短暂排队(maxwait 秒级)属正常,可用 reserve_pool_size 吸收突发。

Q5:客户端报 FATAL: database "appdb" is disabled / no such database? 前者是控制台执行过 DISABLE appdb(维护窗口用,恢复用 ENABLE appdb);后者是连接串里的库名不在 [databases] 映射里,要么补映射要么改用 * 通配行。

Q6:升级 1.26 后原来用的 SUSPEND 命令报错? 1.26.0 已移除 SUSPEND 与 SHOW FDS(连同 -R takeover 机制),平滑发布请改用 so_reuseport 多实例滚动重启方案。管理命令的完整实测清单见 《PgBouncer 1.26.1 常用 CLI 命令与工具详解》。

十、参考链接