Pgbouncer 连接池管理

使用 Pgbouncer 管理连接池,包括暂停、恢复、禁用、启用、重连、终止、重载等操作。

概览

Pigsty 使用 Pgbouncer 作为 PostgreSQL 的连接池中间件,默认监听 6432 端口,代理访问本机 5432 端口上的 PostgreSQL 实例。

这是一个 可选组件,如果您并没有海量链接,也不需要事务池化与查询监控指标,可以关闭连接池,直连数据库,或者保留但不使用。


用户与数据库管理

Pgbouncer 的中用户和数据库由 Pigsty 自动管理,并在 创建数据库创建用户 时自动应用 数据库配置用户配置

数据库管理:在 pg_databases 中定义的数据库,默认会自动添加到 Pgbouncer。设置 pgbouncer: false 可以排除特定数据库。

pg_databases:
  - name: mydb                # 默认加入连接池
    pool_mode: transaction    # 数据库级池化模式
    pool_size: 64             # 默认池大小
  - name: internal
    pgbouncer: false          # 不加入连接池

用户管理:在 pg_users 中定义的用户,需要显式设置 pgbouncer: true 才会加入连接池用户列表。

pg_users:
  - name: dbuser_app
    password: DBUser.App
    pgbouncer: true           # 加入连接池用户列表
    pool_mode: transaction    # 用户级池化模式

服务管理

在 Pigsty 中,PostgreSQL 集群的 Primary 服务 与 Replica 服务默认指向 Pgbouncer 6432 端口, 如果您想要让这两个服务绕过连接池直接访问 PostgreSQL 实例,可以定制 pg_services,或将将 pg_default_service_dest 设置为 postgres


配置管理

Pgbouncer 的配置文件位于 /etc/pgbouncer/ 目录,由 Pigsty 统一生成与管理:

文件说明
pgbouncer.ini主配置文件,连接池级别参数
database.txt数据库列表,数据库级别参数
userlist.txt用户密码列表
useropts.txt用户级别的连接池参数
pgb_hba.confHBA 访问控制规则

Pigsty 会自动管理 database.txtuserlist.txt,在 创建数据库创建用户 时自动更新这些文件。

您也可以手动编辑配置文件后执行 RELOAD 使其生效:

# 编辑配置
$ vim /etc/pgbouncer/pgbouncer.ini

# 重载生效:通过 systemctl
$ sudo systemctl reload pgbouncer

# 重载生效,本身是 pg_dbsu / postgres 用户
$ pgb -c "RELOAD;"

连接池管理

Pgbouncer 使用和 PostgreSQL 相同的 dbsu 运行,默认为 postgres 操作系统用户。Pigsty 提供了快捷命令 pgb 来简化管理操作:

alias pgb="psql -p 6432 -d pgbouncer -U postgres"

您可以在数据库节点上使用 pgb 命令连接到 Pgbouncer 管理控制台,执行管理命令和监控查询。

$ pgb
pgbouncer=# SHOW POOLS;
pgbouncer=# SHOW CLIENTS;
pgbouncer=# SHOW SERVERS;
命令功能说明
PAUSE暂停暂停数据库连接,等待事务完成后断开服务端连接
RESUME恢复恢复被 PAUSE/KILL/SUSPEND 暂停的数据库
DISABLE禁用拒绝指定数据库的新客户端连接
ENABLE启用允许指定数据库的新客户端连接
RECONNECT重连优雅地关闭并重建服务端连接
KILL终止立即断开指定数据库的所有客户端和服务端连接
KILL_CLIENT杀客户端终止指定的客户端连接
SUSPEND挂起刷新缓冲区并停止监听,用于在线重启
SHUTDOWN关闭关闭 Pgbouncer 进程
RELOAD重载重新加载配置文件
WAIT_CLOSE等待关闭等待 RECONNECT/RELOAD 后的服务端连接释放
监控命令监控查看连接池状态、客户端、服务端等信息

PAUSE

使用 PAUSE 命令暂停数据库连接。Pgbouncer 会根据池化模式等待活动事务/会话完成后断开服务端连接。新的客户端请求会被阻塞直到执行 RESUME

PAUSE [db];           -- 暂停指定数据库,不指定则暂停所有数据库

典型使用场景:

  • 在线切换后端数据库(如主从切换后更新连接目标)
  • 执行需要断开所有连接的维护操作
  • 配合 SUSPEND 实现 Pgbouncer 在线重启
$ pgb -c "PAUSE mydb;"        # 暂停 mydb 数据库
$ pgb -c "PAUSE;"             # 暂停所有数据库

暂停后,SHOW DATABASES 会显示 paused 状态:

pgbouncer=# SHOW DATABASES;
   name   |   host    | port | database | ... | paused | disabled
----------+-----------+------+----------+-----+--------+----------
 mydb     | /var/run  | 5432 | mydb     | ... |      1 |        0

RESUME

使用 RESUME 命令恢复被 PAUSEKILLSUSPEND 暂停的数据库,允许新的连接请求并恢复正常服务。

RESUME [db];          -- 恢复指定数据库,不指定则恢复所有数据库
$ pgb -c "RESUME mydb;"       # 恢复 mydb 数据库
$ pgb -c "RESUME;"            # 恢复所有数据库

DISABLE

使用 DISABLE 命令禁用指定数据库,拒绝所有新的客户端连接请求。已存在的连接不受影响。

DISABLE db;           -- 禁用指定数据库(必须指定数据库名)

典型使用场景:

  • 临时下线某个数据库进行维护
  • 阻止新连接以便安全地进行数据库迁移
  • 逐步下线即将删除的数据库
$ pgb -c "DISABLE mydb;"      # 禁用 mydb,新连接被拒绝

ENABLE

使用 ENABLE 命令启用之前被 DISABLE 禁用的数据库,重新接受新的客户端连接。

ENABLE db;            -- 启用指定数据库(必须指定数据库名)
$ pgb -c "ENABLE mydb;"       # 启用 mydb,允许新连接

RECONNECT

使用 RECONNECT 命令优雅地重建服务端连接。Pgbouncer 会在连接释放回池后关闭它们,并在需要时建立新连接。

RECONNECT [db];       -- 重建指定数据库的服务端连接,不指定则重建所有

典型使用场景:

  • 后端数据库 IP 地址变更后刷新连接
  • 主从切换后重新路由流量
  • DNS 更新后重建连接
$ pgb -c "RECONNECT mydb;"    # 重建 mydb 的服务端连接
$ pgb -c "RECONNECT;"         # 重建所有服务端连接

执行 RECONNECT 后,可以使用 WAIT_CLOSE 等待旧连接完全释放。


KILL

使用 KILL 命令立即断开指定数据库的所有客户端和服务端连接。与 PAUSE 不同,KILL 不等待事务完成,直接强制断开。

KILL [db];            -- 终止指定数据库的所有连接,不指定则终止所有(admin 除外)
$ pgb -c "KILL mydb;"         # 强制断开 mydb 的所有连接
$ pgb -c "KILL;"              # 强制断开所有数据库的连接(admin 除外)

执行 KILL 后,新连接会被阻塞直到执行 RESUME


KILL_CLIENT

使用 KILL_CLIENT 命令终止指定的客户端连接。客户端 ID 可以从 SHOW CLIENTS 输出中获取。

KILL_CLIENT id;       -- 终止指定 ID 的客户端连接
# 查看客户端连接
$ pgb -c "SHOW CLIENTS;"

# 终止特定客户端(假设 ptr 列显示的 ID 为 0x1234567890)
$ pgb -c "KILL_CLIENT 0x1234567890;"

SUSPEND

使用 SUSPEND 命令挂起 Pgbouncer。Pgbouncer 会刷新所有 socket 缓冲区并停止监听数据,直到执行 RESUME

SUSPEND;              -- 挂起 Pgbouncer

SUSPEND 主要用于实现 Pgbouncer 的在线重启(零停机升级):

# 1. 挂起当前 Pgbouncer
$ pgb -c "SUSPEND;"

# 2. 启动新的 Pgbouncer 进程(使用 -R 选项接管 socket)
$ pgbouncer -R /etc/pgbouncer/pgbouncer.ini

# 3. 新进程接管后,旧进程自动退出

SHUTDOWN

使用 SHUTDOWN 命令关闭 Pgbouncer 进程。支持多种关闭模式:

SHUTDOWN;                      -- 立即关闭
SHUTDOWN WAIT_FOR_SERVERS;     -- 等待服务端连接释放后关闭
SHUTDOWN WAIT_FOR_CLIENTS;     -- 等待客户端断开后关闭(零停机滚动重启)
模式说明
SHUTDOWN立即关闭 Pgbouncer 进程
WAIT_FOR_SERVERS停止接受新连接,等待服务端连接释放后退出
WAIT_FOR_CLIENTS停止接受新连接,等待所有客户端断开后退出,适用于滚动重启
$ pgb -c "SHUTDOWN WAIT_FOR_CLIENTS;"   # 优雅关闭,等待客户端断开

RELOAD

使用 RELOAD 命令重新加载 Pgbouncer 配置文件。可以动态更新大部分配置参数,无需重启进程。

RELOAD;               -- 重载配置文件
$ pgb -c "RELOAD;"              # 通过管理控制台重载
$ systemctl reload pgbouncer    # 通过 systemd 重载
$ kill -SIGHUP $(cat /var/run/pgbouncer/pgbouncer.pid)  # 通过信号重载

Pigsty 提供了重载 Pgbouncer 配置的剧本任务:

./pgsql.yml -l <cls> -t pgbouncer_reload    # 重载集群的 Pgbouncer 配置

WAIT_CLOSE

使用 WAIT_CLOSE 命令等待服务端连接完成关闭。通常在 RECONNECTRELOAD 后使用,确保旧连接已全部释放。

WAIT_CLOSE [db];      -- 等待指定数据库的服务端连接关闭,不指定则等待所有
# 完整的连接重建流程
$ pgb -c "RECONNECT mydb;"
$ pgb -c "WAIT_CLOSE mydb;"    # 等待旧连接释放

监控命令

Pgbouncer 提供了丰富的 SHOW 命令用于监控连接池状态:

命令说明
SHOW HELP显示可用命令帮助
SHOW DATABASES显示数据库配置和状态
SHOW POOLS显示连接池统计信息
SHOW CLIENTS显示客户端连接列表
SHOW SERVERS显示服务端连接列表
SHOW USERS显示用户配置
SHOW STATS显示统计信息(请求数、字节数等)
SHOW STATS_TOTALS显示累计统计信息
SHOW STATS_AVERAGES显示平均统计信息
SHOW CONFIG显示当前配置参数
SHOW MEM显示内存使用情况
SHOW DNS_HOSTS显示 DNS 缓存的主机名
SHOW DNS_ZONES显示 DNS 缓存的区域
SHOW SOCKETS显示打开的 socket 信息
SHOW ACTIVE_SOCKETS显示活动的 socket
SHOW LISTS显示内部列表计数
SHOW FDS显示文件描述符使用情况
SHOW STATE显示 Pgbouncer 运行状态
SHOW VERSION显示 Pgbouncer 版本

常用监控示例:

# 查看连接池状态
$ pgb -c "SHOW POOLS;"

# 查看客户端连接
$ pgb -c "SHOW CLIENTS;"

# 查看服务端连接
$ pgb -c "SHOW SERVERS;"

# 查看统计信息
$ pgb -c "SHOW STATS;"

# 查看数据库状态
$ pgb -c "SHOW DATABASES;"

更多监控命令的详细说明,请参考 Pgbouncer 官方文档


Unix 信号

Pgbouncer 支持通过 Unix 信号进行控制,这在无法连接管理控制台时非常有用:

信号等效命令说明
SIGHUPRELOAD重载配置文件
SIGTERMSHUTDOWN WAIT_FOR_CLIENTS优雅关闭,等待客户端断开
SIGINTSHUTDOWN WAIT_FOR_SERVERS优雅关闭,等待服务端释放
SIGQUITSHUTDOWN立即关闭
SIGUSR1PAUSE暂停所有数据库
SIGUSR2RESUME恢复所有数据库
# 通过信号重载配置
$ kill -SIGHUP $(cat /var/run/pgbouncer/pgbouncer.pid)

# 通过信号优雅关闭
$ kill -SIGTERM $(cat /var/run/pgbouncer/pgbouncer.pid)

# 通过信号暂停
$ kill -SIGUSR1 $(cat /var/run/pgbouncer/pgbouncer.pid)

# 通过信号恢复
$ kill -SIGUSR2 $(cat /var/run/pgbouncer/pgbouncer.pid)

流量切换

Pigsty 提供了 pgb-route 实用函数,可以将 Pgbouncer 流量快速切换至其他节点,用于零停机迁移:

# 定义(已在 /etc/profile.d/pg-alias.sh 中)
function pgb-route(){
  local ip=${1-'\/var\/run\/postgresql'}
  sed -ie "s/host=[^[:space:]]\+/host=${ip}/g" /etc/pgbouncer/pgbouncer.ini
  cat /etc/pgbouncer/pgbouncer.ini
}

# 使用:将流量路由到 10.10.10.12
$ pgb-route 10.10.10.12
$ pgb -c "RECONNECT; WAIT_CLOSE;"

完整的零停机切换流程:

# 1. 修改路由目标
$ pgb-route 10.10.10.12

# 2. 重载配置
$ pgb -c "RELOAD;"

# 3. 重建连接并等待旧连接释放
$ pgb -c "RECONNECT;"
$ pgb -c "WAIT_CLOSE;"