适用连接池可以有效的降低反复连接造成的损耗,但是如果使用不当也会造成混淆和错乱,建议根据需求进行测试,同时规范内部代码
2025.5.15更新,演示:1.24.1版本
本文默认是以linux为演示,windows下类似,但是

没有安装pgsql的可以参考:pgsql编译安装

一、编译安装

包安装更简单,就是不能选版本

1.pgBouncer下载地址

链接:github项目地址
链接:pgbouncer官网

2.下载

进入目录

cd /usr/local

官网下载

wget https://www.pgbouncer.org/downloads/files/1.24.1/pgbouncer-1.24.1.tar.gz

或者
github下载

wget https://github.com/pgbouncer/pgbouncer/releases/download/pgbouncer_1_24_1/pgbouncer-1.24.1.tar.gz

3.解压

tar -zxvf pgbouncer-1.24.1.tar.gz && cd pgbouncer-1.24.1

4.依赖安装

apt-get install libevent-dev libsystemd-dev

5.编译安装

更多参数参考官方文档:官方文档

./configure --prefix=/usr/local --with-systemd --with-pam --enable-debug --enable-evdns --enable-tls
make && make install

安装完成后提示相关文件位置如下:
在这里插入图片描述

二、模式和原理

(一)会话模式

实际使用第二级的比较多,但是如果出现混淆,应急情况下切换为第一级测试

1.Session pooling/会话连接池(最安全)

这种方式和不用连接池差不多,效果不明显,但是最安全,无需修改现有代码。
session,会话级连接,在客户端连接的生命周期内,连接池分配一个连接给它,直到客户端断开连接,分配的连接才会回到连接池中。

2.Transaction pooling/事务连接池(推荐)

服务器连接只有在一个事务里的时候才赋予客户端。在 PgBouncer 注意到事务结束的时候,服务器将会放回连接池中。这是一个 hack,因为它打破了应用对后段连接的看法。只有在应用配合这样的使用模式,没有使用会破坏这种使用模式的时候才能用这个连接方式。参阅下标获取会破坏 这种模式的特性。

3.Statement pooling/语句连接池(谨慎使用)

最激进的模式。这是事务连接池的一个扭曲的变种 - 不允许多语句的事务。这就意味着是在客户端强制“autocomit”模式,主要是给 PL/Proxy 用的。

三、配置、管理

(一)配置文件

1.建立配置文件

个人习惯将配置文件存放到/etc目录下

mkdir /etc/pgbouncer

复制配置文件

cp /usr/local/share/doc/pgbouncer/pgbouncer.ini /etc/pgbouncer

2.创建日志需要的目录

创建日志目录和日志文件

mkdir -p /var/pgbouncer

移交所有权给postgres用户(linux的pgsql,习惯上用这个用户)

chown postgres:postgres /var/pgbouncer

3.编辑配置文件

没有说到的配置使用默认即可,无需删除前面的注释;

vi /etc/pgbouncer/pgbouncer.ini

添加数据库连接[database]下
账号密码是pgsql的账号密码,用于连接已有的pgsql数据库
找到[databases],这里的最前面的名称main_pg,就是关联的后面的源数据库的postgres库,连接时用main_pg作为虚拟的数据库,代替后面的localhost:5432的postgres数据库,相当于一个别名,到时候连接的时候就连接这个main_pg虚拟的数据库

[databases]
main_pg = host=localhost port=5432 dbname=postgres user=postgres password=abc123456 

修改log和pid地址

logfile = /var/log/pgbouncer/pgbouncer.log
pidfile = /var/run/pgbouncer/pgbouncer.pid

允许外部访问
listen_addr = *
默认是localhost,就是只允许本机访问,如果是单机系统可以不改

修改admin_users
如果没有认证,这个参数就失效了,注意postgres是pgsql默认的管理员账号,如果你修改了,这里也要变

admin_users = postgres

修改每个池最大连接数
找到max_client_conn,修改为900,删除前面的;

max_client_conn = 900

修改连接池数
找到default_pool_size ,修改为50,删除前面的;

default_pool_size =50

保存连接池大小
找到reserve_pool_size,修改为20,取消前面;注释

reserve_pool_size = 20

空闲连接超时
找到server_idle_timeout,修改为60,取消前面;注释

server_idle_timeout = 60

单个查询超时
找到query_timeout ,修改为60,取消前面;注释

query_timeout = 60

连接生存周期
找到server_lifetime,修改为300,取消前面;注释

server_lifetime = 300

修改连接池模式
找到pool_mode = session,修改为下面的,并删除前面的;默认的连接池是session

pool_mode = transaction

设置ignore_startup_parameters
删除前面的;

ignore_startup_parameters = extra_float_digits

(二)连接文件配置

1.复制认证文件

cp /usr/local/share/doc/pgbouncer/userlist.txt /etc/pgbouncer

2.编辑数据库账号密码文件

vi /etc/pgbouncer/userlist.txt

改成类似如下的形式,前面是pgsql的用户名,postgres是默认的账号名,密码为明文密码,
形如以下部分

"postgres" "abc123456"

这个密码是连接pgbouncer的密码,可以和pgsql源库的密码不一致,这样也是相当于多了一层保护
也可以设置为一样,都可以。

(三)systemctl管理

1.复制systemctl文件

cp /usr/local/share/doc/pgbouncer/pgbouncer.service /lib/systemd/system

2.编辑文件

vi /lib/systemd/system/pgbouncer.service

修改ExecStart地址(编译完成后会提示)
按照我的目录是/usr/local/bin

在这里插入图片描述

3.启动程序

systemctl daemon-reload && systemctl start pgbouncer

4.查看状态

如果出错,也是这里查看,在最后一节有各种错误的处理方法

systemctl status pgbouncer

(四)连接测试

1.进入pgBouncer的psql

su postgres
psql -p 6432 pgbouncer

密码为上面设定的连接文件里的密码

2.pgbouncer自带的命令

显示所有配置

show config; 

显示所有客户连接

show clients;

显示所有的源数据库

show servers;

四、使用和优化

1.连接原理

使用psql连接pgbouncer的main_pg数据库(pgbouncer此时连接main_pg的源数据库)
通过这种方式实现了pgsql的池。

psql -h localhost -p 6432 -U postgres -d main_pg

此时在源数据库中输入命令即可查询到pgbouncer的连接

select * from pg_stat_activity;

2.后端程序中调用

在这个案例中,后端连接6432端口的main_pg数据库,即可对应原来的5432端口的postgres数据库
只需要修改连接地址即可,无需调整后端逻辑(除非变成第三种模式,不推荐)

3.日志管理和自动清理

使用系统自带工具logrotate

vi /etc/logrotate.d/pgbouncer

内容如下,这里只作解释,复制下面没有注释的,避免出错:

/var/pgbouncer/pgbouncer.log {
    daily                          # 每日分割
    rotate 7                      # 保留7天的日志
    compress                       # 使用 gzip 压缩旧日志
    delaycompress                  # 延迟一天再压缩,避免影响当前写入
    missingok                      # 如果日志不存在则忽略
    notifempty                     # 忽略空文件
    copytruncate                   # 复制并截断原日志,防止进程停止写入
    su postgres postgres           # 以 postgres 用户权限执行
    create 640 postgres postgres   # 创建新的日志文件,权限为 640
    sharedscripts                  # 确保所有的命令只执行一次
    postrotate
        /usr/local/bin/pgbouncer -R      # 重新加载 pgbouncer 日志
    endscript
}

保存退出即可,建议把注释内容删除,否则极易出错

/var/pgbouncer/pgbouncer.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    su postgres postgres
    create 640 postgres postgres
    sharedscripts
    postrotate
        /usr/local/bin/pgbouncer -R
    endscript
}

可以手动测试

logrotate -f /etc/logrotate.d/pgbouncer

正常不会报错

五、升级

如果未来版本更新,需要升级
为了稳妥,备份现有配置文件,关闭现有程序,然后重新编译,再启动

六、错误和处理

1.文件描述限制-谨慎修改

kernel file descriptor limit: 1024 (hard: 1048576); max_client_conn: 1000, max expected fd use: 1062

永久生效,应对重启服务器后的情况:
修改/etc/security/limits.conf

vi /etc/security/limits.conf

添加内容如下(不要删除前面的*):

* soft nofile 65535
* hard nofile 65535

修改/etc/sysctl.conf

vi /etc/sysctl.conf
fs.file-max = 65535

生效

sysctl -p

2.PID文件路径问题

FATAL could not open pidfile ‘/var/run/pgbouncer/pgbouncer.pid’: No such file or directory
手动创建目录

mkdir -p /var/run/pgbouncer
chown postgres:postgres /var/run/pgbouncer
chmod 775 /var/run/pgbouncer
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐