这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

pgBouncer 1.25 中文文档

PgBouncer —— PostgreSQL 轻量级连接池,v1.25 中文文档

原始页面: https://www.pgbouncer.org/

pgbouncer 是 PostgreSQL 的连接池。任何目标应用都可以像连接 PostgreSQL 服务器一样连接到 pgbouncerpgbouncer 将负责创建到实际服务器的连接,或者复用已有的连接。

pgbouncer 的目标是降低向 PostgreSQL 建立新连接所带来的性能损耗。

为了在连接池化时不破坏事务语义,pgbouncer 在轮换连接时支持多种池化类型:

  • 会话池化:最温和的方式。当客户端连接时,将为其分配一个服务端连接,并在客户端保持连接期间始终持有。当客户端断开时,服务端连接将放回连接池。这是默认方式。
  • 事务池化:仅在事务期间为客户端分配服务端连接。当 PgBouncer 检测到事务结束时,服务端连接将放回连接池。
  • 语句池化:最激进的方式。查询完成后,服务端连接立即放回连接池。此模式禁止多语句事务。

1 - 特性

PgBouncer 特性——池化模式与 SQL 兼容性

原始页面: https://www.pgbouncer.org/features.html

  • 连接轮换时,按激进程度分为以下几种策略:

    会话池化
    最温和的方式。当客户端连接时,将为其分配一个服务端连接,并在客户端保持连接期间始终持有。当客户端断开时,服务端连接将放回连接池。此模式支持所有 PostgreSQL 特性。
    事务池化
    仅在事务期间为客户端分配服务端连接。当 PgBouncer 检测到事务结束时,服务端连接将放回连接池。此模式会破坏 PostgreSQL 的部分会话级特性,只有在应用程序配合、不使用不兼容特性的情况下才可使用。不兼容特性详见下表。
    语句池化
    最激进的方式。这是事务池化的变体:禁止多语句事务。这是为了在客户端强制执行“自动提交”(autocommit)模式,主要面向 PL/Proxy。
  • 内存占用极低(默认每连接仅需 2 kB)。这是因为 PgBouncer 无需一次性看到完整的数据包。

  • 不绑定到单一后端服务器。目标数据库可以分布在不同的主机上。

  • 支持大多数配置项的在线重新配置。

  • 支持在不断开客户端连接的情况下在线重启/升级。


各池化模式的 SQL 特性兼容表

下表列出了 PostgreSQL 的各项特性及其与 PgBouncer 池化模式的兼容性。请注意,事务池化在设计上就会打破客户端对服务端的预期,只有在应用程序配合、不使用不可用特性的情况下方可使用。

特性会话池化事务池化
Startup parameters 1
SET/RESET不支持
LISTEN不支持
NOTIFY
WITHOUT HOLD CURSOR
WITH HOLD CURSOR不支持
Protocol-level prepared plans2
PREPARE / DEALLOCATE不支持
ON COMMIT DROP temp tables
PRESERVE/DELETE ROWS temp tables不支持
Cached plan reset
LOAD statement不支持
Session-level advisory locks不支持

  1. 启动参数包括:client_encodingDateStyleIntervalStyleTimezonestandard_conforming_stringsapplication_name。PgBouncer 会检测这些参数的变化,从而确保客户端获得一致的值。如果需要 PgBouncer 支持更多启动参数,请参阅 track_extra_parametersignore_startup_parameters。 ↩︎

  2. 需要将 max_prepared_statements 设置为非零值以启用此支持。 ↩︎

2 - 配置:pgbouncer.ini

PgBouncer 配置文件(pgbouncer.ini)完整参考

原始页面: https://www.pgbouncer.org/config.html


描述

配置文件采用 “ini” 格式。节名称位于 [] 之间。以 ;# 开头的行被视为注释并忽略。当 ;# 出现在行中间时,不会被识别为特殊字符。


通用设置

logfile

指定日志文件。若要以守护进程方式运行(-d),需要设置此项或 syslog

日志文件保持打开状态,因此在日志轮转后,应执行 kill -HUP 或在控制台执行 RELOAD;。在 Windows 上,必须停止并重启服务。

注意:设置 logfile 本身并不会关闭向 stderr 的日志输出,如需关闭请使用命令行选项 -q-d

默认值:未设置

pidfile

指定 PID 文件。若未设置 pidfile,则不允许以守护进程方式运行(-d)。

默认值:未设置

listen_addr

指定监听 TCP 连接的地址列表(逗号分隔)。也可使用 * 表示"监听所有地址"。若未设置,则只接受 Unix 套接字连接。

地址可以用数字形式(IPv4/IPv6)或主机名指定。

默认值:未设置

listen_port

监听的端口号。同时适用于 TCP 和 Unix 套接字。

默认值:6432

unix_socket_dir

指定 Unix 套接字的位置。同时适用于监听套接字和服务端连接。若设为空字符串,则禁用 Unix 套接字。以 @ 开头的值表示创建抽象命名空间中的 Unix 套接字(目前仅支持 Linux 和 Windows)。

若要使在线重启(-R)正常工作,需要配置 Unix 套接字,且必须位于文件系统命名空间中。

默认值:/tmp(Windows 上为空)

unix_socket_mode

Unix 套接字的文件系统权限模式。对抽象命名空间中的套接字无效,Windows 上不支持。

默认值:0777

unix_socket_group

Unix 套接字使用的组名。对抽象命名空间中的套接字无效,Windows 上不支持。

默认值:未设置

user

若设置此项,则在启动后切换到指定的 Unix 用户。仅当 PgBouncer 以 root 启动或已以指定用户运行时有效,Windows 上不支持。

默认值:未设置

pool_mode

指定服务端连接何时可被其他客户端复用。

  • session:客户端断开连接后,服务端连接被归还到连接池。默认值。
  • transaction:事务结束后,服务端连接被归还到连接池。
  • statement:查询结束后,服务端连接被归还到连接池。在此模式下,不允许跨多条语句的事务。

max_client_conn

允许的最大客户端连接数。

增大此设置时,操作系统的文件描述符限制可能也需要相应提高。注意,实际可能使用的文件描述符数量多于 max_client_conn。如果每个用户以自己的用户名连接到服务器,理论最大值为:

max_client_conn + (max pool_size * total databases * total users)

如果连接字符串中指定了数据库用户(所有用户以同一用户名连接),理论最大值为:

max_client_conn + (max pool_size * total databases)

理论最大值通常不会被达到,除非有人刻意构造特殊负载。尽管如此,这意味着你应该将文件描述符数量设置到一个足够大的安全值。

在你喜欢的 shell 手册页中搜索 ulimit。注意:ulimit 在 Windows 环境中不适用。

默认值:100

default_pool_size

每个用户/数据库对允许的服务端连接数。可在每个数据库的配置中覆盖。

默认值:20

min_pool_size

若连接池中的连接数低于此值,则向连接池添加更多服务端连接。在长时间完全空闲后恢复正常负载时,可改善响应行为。该值实际上被限制在连接池大小以内。

仅在以下至少一个条件满足时才强制执行:

  • [database] 节中该连接池的条目设置了 user 键(即强制用户)
  • 该连接池中至少有一个客户端连接

默认值:0(禁用)

reserve_pool_size

允许向连接池添加的额外连接数(参见 reserve_pool_timeout)。0 表示禁用。

默认值:0(禁用)

reserve_pool_timeout

如果客户端在此时间内未被服务,则使用备用连接池中的额外连接。0 表示禁用。[秒]

默认值:5.0

max_db_connections

每个数据库允许的最大服务端连接数(不区分用户)。这里指的是客户端所连接的 PgBouncer 数据库,而非出站连接对应的 PostgreSQL 数据库。

也可在 [databases] 节中按数据库设置。

注意:达到限制后,关闭某个连接池的客户端连接并不会立即允许另一个连接池建立新的服务端连接,因为第一个连接池的服务端连接仍然是打开的。一旦该服务端连接因空闲超时而关闭,等待中的连接池将立即打开新的服务端连接。

默认值:0(不限制)

max_db_client_connections

每个数据库允许的最大客户端连接数(不区分用户)。这里指的是客户端所连接的 PgBouncer 数据库,而非出站连接对应的 PostgreSQL 数据库。

此值应大于或等于 max_db_connections。两者之差可以理解为:在等待活跃连接完成的过程中,某个数据库可以排队的连接数。

也可在 [databases] 节中按数据库设置。

默认值:0(不限制)

max_user_connections

每个用户允许的最大服务端连接数(不区分数据库)。这里指的是与连接池关联的 PgBouncer 用户,即为服务端连接指定的用户,或在未指定的情况下,客户端所使用的登录用户。

也可在 [users] 节中按用户设置。

注意:达到限制后,关闭某个连接池的客户端连接并不会立即允许另一个连接池建立新的服务端连接,因为第一个连接池的服务端连接仍然是打开的。一旦该服务端连接因空闲超时而关闭,等待中的连接池将立即打开新的服务端连接。

默认值:0(不限制)

max_user_client_connections

每个用户允许的最大客户端连接数(不区分数据库)。此值应高于 max_user_connectionsmax_user_connectionsmax_user_client_connections 之差,可以理解为该用户的最大排队长度。

也可在 [users] 节中按用户设置。

默认值:0(不限制)

server_round_robin

默认情况下,PgBouncer 以 LIFO(后进先出)方式复用服务端连接,从而使少数连接承担大部分负载。当只有一台服务器为某个数据库提供服务时,这种方式性能最佳。但如果数据库地址背后有轮询系统(TCP、DNS 或主机列表),则 PgBouncer 也采用轮询方式使用连接会更好,从而实现均匀的负载分布。

默认值:0

track_extra_parameters

默认情况下,PgBouncer 为每个客户端跟踪 client_encodingdatestyletimezonestandard_conforming_stringsapplication_name 参数。若需跟踪其他参数,可在此处指定,使 PgBouncer 知道应将它们维护在客户端变量缓存中,并在客户端变为活跃状态时将其恢复到服务端。

若需指定多个值,请使用逗号分隔的列表(例如 default_transaction_read_only, IntervalStyle)。

注意:大多数参数无法通过此方式跟踪。只有 Postgres 向客户端报告的参数才能被跟踪。Postgres 有一份 官方报告给客户端的参数列表。不过,Postgres 扩展可以修改此列表——它们可以添加自己上报的参数,也可以开始上报 Postgres 原本未上报的已有参数。值得注意的是,Citus 12.0+ 会导致 Postgres 额外上报 search_path

Postgres 协议支持通过两种方式指定参数设置:直接作为启动包中的参数,或在 options 启动包 中指定。这两种方式指定的参数均受 track_extra_parameters 支持。但 options 本身不能被包含在 track_extra_parameters 中,只有 options 中包含的参数才可以。

默认值:IntervalStyle

ignore_startup_parameters

默认情况下,PgBouncer 在启动包中只允许它可以跟踪的参数:client_encodingdatestyletimezonestandard_conforming_strings。所有其他参数都会触发错误。若要允许其他参数,可在此处指定,PgBouncer 便知道这些参数由管理员处理,可以忽略它们。

若需指定多个值,请使用逗号分隔的列表(例如 options,extra_float_digits)。

Postgres 协议支持通过两种方式指定参数设置:直接作为启动包中的参数,或在 options 启动包 中指定。这两种方式指定的参数均受 ignore_startup_parameters 支持。甚至可以将 options 本身包含在 track_extra_parameters 中,这样 options 中包含的所有未知参数都会被忽略。

默认值:空

peer_id

用于在一组相互对等的 PgBouncer 进程中标识当前 PgBouncer 进程的对等 ID。在一组对等的 PgBouncer 进程中,peer_id 值必须唯一。设为 0 时,PgBouncer 对等功能被禁用。详见 [peers] 节的文档。peer_id 的最大值为 16383。

默认值:0

disable_pqexec

禁用简单查询协议(PQexec)。与扩展查询协议不同,简单查询协议允许在一个数据包中发送多条查询,这可能导致某些类型的 SQL 注入攻击。禁用它可以提高安全性。显然,这意味着只有完全使用扩展查询协议的客户端才能正常工作。

默认值:0

application_name_add_host

在连接建立时,将客户端主机地址和端口追加到 application_name 设置中。这有助于识别问题查询的来源等。此逻辑仅在连接建立时生效。若之后通过 SET 修改了 application_name,PgBouncer 不会再次更改它。

默认值:0

conffile

显示当前配置文件的位置。修改此项将使 PgBouncer 在下次 RELOAD / SIGHUP 时使用另一个配置文件。

默认值:命令行指定的文件

service_name

用于 Win32 服务注册。

默认值:pgbouncer

job_name

service_name 的别名。

stats_period

设置各 SHOW 命令中显示的平均值的更新频率,以及聚合统计信息写入日志的频率(另见 log_stats)。[秒]

默认值:60

max_prepared_statements

当此值设为非零时,PgBouncer 会在事务池化和语句池化模式下,跟踪客户端发送的协议级命名预处理语句相关命令。PgBouncer 会确保客户端发出的任何预处理语句在后端服务端连接上都可用,即使该语句最初是在另一个服务端连接上准备的。

PgBouncer 内部会检查客户端作为预处理语句发送的所有查询,并以 PGBOUNCER_{unique_id} 格式为每个唯一查询字符串分配一个内部名称。如果同一查询字符串被多次准备(可能来自不同客户端),这些查询会共享同一个内部名称。PgBouncer 仅使用内部名称(而非客户端提供的名称)在实际的 PostgreSQL 服务器上准备语句。PgBouncer 会记录客户端为每个预处理语句指定的名称,并在将命令转发到服务器之前,将使用预处理语句的每条命令中的客户端名称替换为内部名称(例如,将 my_prepared_statement 替换为 PGBOUNCER_123)。更重要的是,如果客户端想要执行的预处理语句尚未在服务器上准备好(例如,因为当前分配给客户端的服务器与客户端准备该语句时的服务器不同),PgBouncer 会在执行前透明地进行准备。

注意:对预处理语句命令的跟踪和改写不适用于 SQL 级别的预处理语句命令,因此 PREPAREEXECUTEDEALLOCATE 会直接转发给 Postgres。例外情况是 DEALLOCATE ALLDISCARD ALL 命令,它们可以按预期工作,并会清除 PgBouncer 为发送这些命令的客户端跟踪的预处理语句。

此设置的实际值控制在单个服务端连接上的 LRU 缓存中保持活跃的预处理语句数量。设为 0 时,事务池化和语句池化的预处理语句支持被禁用。为获得最佳性能,应确保此设置大于应用程序中常用预处理语句的数量。请注意,该值越高,PgBouncer 每个连接在 PostgreSQL 服务器上的内存占用就越大,因为服务器会保持更多已准备好的查询。这也会增加 PgBouncer 自身的内存占用,因为它需要跟踪查询字符串。

不过,PgBouncer 内存使用的影响并不太大:

  • 每个唯一查询在全局查询缓存中只存储一次。
  • 每个客户端连接都保留一个用于改写数据包的缓冲区,大小最多为 pkt_buf 的 4 倍。但这个上限通常不会被达到,只有在预处理语句中的查询大小介于 pkt_buf 的 2 到 4 倍之间时才会出现。

以如下示例场景为例:

  • 有 1000 个活跃客户端
  • 客户端准备了 200 个唯一查询
  • 查询的平均大小为 5kB
  • pkt_buf 参数设置为默认值 4096(4kB)

那么,PgBouncer 处理这些预处理语句所需的最大内存量为:

200 x 5kB + 1000 x 4 x 4kB = ~17MB of memory.

跟踪预处理语句不仅有内存开销,还会增加 CPU 使用率,因为 PgBouncer 需要检查和改写查询。多个 PgBouncer 实例可以监听同一端口,以使用多个核心进行处理,详情参见 so_reuseport 选项的文档

当然,预处理语句也有性能优势。就像直接连接 PostgreSQL 一样,通过预先准备一个多次执行的查询,可以减少总体的解析和规划开销。PgBouncer 跟踪预处理语句的方式对性能尤其有益,特别是当多个客户端准备相同查询时。因为客户端连接会自动在服务端连接上复用预处理语句,即使该语句是由其他客户端准备的。例如,如果 pool_size 为 20,且有 100 个客户端都准备了完全相同的查询,那么该查询在 PostgreSQL 服务器上只会被准备(即解析)20 次。

复用预处理语句有一个缺点。如果预处理语句的返回类型或参数类型在多次执行之间发生变化,PostgreSQL 当前会抛出如下错误:

ERROR:  cached plan must not change result type

避免此类错误的方法是:不要让多个客户端使用完全相同的查询字符串的预处理语句,但期望不同的参数或返回类型。最常见的触发场景是在 DDL 迁移期间,对现有表添加新列或更改列类型。在这种情况下,可以在完成迁移后在 PgBouncer 管理控制台上运行 RECONNECT,强制重新准备查询以消除该错误。

默认值:200

scram_iterations

使用 SCRAM-SHA-256 加密密码时执行的计算迭代次数。迭代次数越多,对已存储密码的暴力破解攻击的防护越强,但也会使认证速度变慢。

默认值:4096


认证设置

PgBouncer 处理自己的客户端认证,并维护自己的用户数据库。这些设置用于控制此行为。

auth_type

用户认证方式。

  • cert:客户端必须通过 TLS 连接并提供有效的客户端证书。用户名从证书的 CommonName 字段中获取。
  • md5:使用基于 MD5 的密码验证。这是默认的认证方式。auth_file 可以同时包含 MD5 加密和明文密码。若配置了 md5 但某用户拥有 SCRAM 密钥,则自动使用 SCRAM 认证。
  • scram-sha-256:使用 SCRAM-SHA-256 进行密码验证。auth_file 必须包含 SCRAM 密钥或明文密码。
  • plain:明文密码通过网络传输。已弃用。
  • trust:不进行认证。用户名仍必须存在于 auth_file 中。
  • any:类似 trust 方式,但忽略所提供的用户名。要求所有数据库都配置为以特定用户登录。此外,控制台数据库允许任何用户以管理员身份登录。
  • hba:实际的认证类型从 auth_hba_file 加载。这允许为不同的访问路径使用不同的认证方式,例如:通过 Unix 套接字的连接使用 peer 认证方式,通过 TCP 的连接必须使用 TLS。
  • ldap:用户通过 LDAP 服务器认证,与 PostgreSQL 中的方式类似(详见 https://www.postgresql.org/docs/current/auth-ldap.html)。LDAP 连接选项通过 auth_ldap_options 设置配置,也可在 auth_hba_file 中配置。
  • pam:使用 PAM 认证用户,忽略 auth_file。此方法与使用 auth_user 选项的数据库不兼容。报告给 PAM 的服务名称为 “pgbouncer”。pam 在 HBA 配置文件中不受支持。

auth_hba_file

auth_typehba 时使用的 HBA 配置文件。详见下方 HBA 文件格式 节。

默认值:未设置

auth_ident_file

auth_typehba 且需要定义用户映射时使用的身份映射文件。详见下方 Ident 映射文件格式 节。

默认值:未设置

auth_file

用于加载用户名和密码的文件名。详见下方 认证文件格式 节。

大多数认证类型(见上文)要求设置 auth_fileauth_user,否则将没有用户定义。

默认值:未设置

auth_user

若设置了 auth_user,则任何未在 auth_file 中指定的用户,都将通过 auth_query 查询从数据库的 pg_authid 中获取密码,使用的是 auth_userauth_user 的密码从 auth_file 中获取。(如果 auth_user 不需要密码,则不需要在 auth_file 中定义。)

直接访问 pg_authid 需要管理员权限。建议使用调用 SECURITY DEFINER 函数的非超级用户替代。

默认值:未设置

auth_query

用于从数据库加载用户密码的查询。

直接访问 pg_authid 需要管理员权限。建议使用调用 SECURITY DEFINER 函数的非超级用户替代。

注意:该查询在目标数据库内部运行。因此,若使用函数,需要将其安装到每个数据库中。

默认值:SELECT rolname, CASE WHEN rolvaliduntil < now() THEN NULL ELSE rolpassword END FROM pg_authid WHERE rolname=$1 AND rolcanlogin

auth_dbname

[database] 节中用于认证目的的数据库名称。此选项可以是全局设置,也可以在连接字符串中指定该参数来覆盖全局设置。

auth_ldap_options

auth_typeldap 时使用的 LDAP 连接选项。(若通过 auth_hba_file 配置认证,则不使用此项。)示例:

auth_ldap_options = ldapurl="ldap://127.0.0.1:12345/dc=example,dc=net?uid?sub"

日志设置

syslog

开启/关闭 syslog。在 Windows 上,使用事件日志替代。

默认值:0

syslog_ident

发送日志到 syslog 时使用的名称。

默认值:pgbouncer(程序名)

syslog_facility

发送日志到 syslog 时使用的设施(facility)。可选值:authauthprivdaemonuserlocal0-7

默认值:daemon

log_connections

记录成功的登录。

默认值:1

log_disconnections

记录断开连接及其原因。

默认值:1

log_pooler_errors

记录连接池向客户端发送的错误消息。

默认值:1

log_stats

每隔 stats_period 将聚合统计信息写入日志。如果使用外部监控工具通过 SHOW 命令获取相同数据,可以禁用此项。

默认值:1

verbose

增加日志详细程度。与命令行上的 -v 开关效果相同。例如,命令行上使用 -v -v 等同于 verbose=2。3 是目前支持的最高详细级别。

默认值:0


控制台访问控制

admin_users

允许连接并在控制台执行所有命令的数据库用户(逗号分隔列表)。当 auth_typeany 时忽略此项,此时任何用户名都被允许作为管理员登录。

默认值:空

stats_users

允许连接并在控制台执行只读查询的数据库用户(逗号分隔列表)。即除 SHOW FDS 外的所有 SHOW 命令。

默认值:空


连接健康检查与超时

server_reset_query

在将服务端连接释放给其他客户端之前,向服务器发送的查询。此时没有进行中的事务,因此该值不应包含 ABORTROLLBACK

该查询用于清除对数据库会话所做的任何更改,以便下一个客户端获得处于明确已知状态的连接。默认值为 DISCARD ALL,它会清除所有内容,但这使下一个客户端没有任何预缓存的状态。可以设置得更轻量,例如仅使用 DEALLOCATE ALL 来清除预处理语句,前提是应用程序在保留部分状态时不会出错。

使用事务池化时,不使用 server_reset_query,因为在该模式下,客户端不得使用任何基于会话的功能,因为每个事务最终会在不同的连接上执行,从而获得不同的会话状态。

默认值:DISCARD ALL

server_reset_query_always

是否在所有池化模式下都运行 server_reset_query。当此设置关闭时(默认),server_reset_query 只会在会话池化模式的连接池中运行。事务池化模式的连接不应需要重置查询。

此设置用于变通处理一种异常配置:应用程序通过事务池化的 PgBouncer 使用了会话级功能。它将不确定性故障转变为确定性故障:客户端在每次事务后都会丢失会话状态。

默认值:0

server_check_delay

释放的连接在无需运行 server_check_query 的情况下,可供立即重用的时间长度。若为 0,则每次都运行检查。

默认值:30.0

server_check_query

用于检查服务端连接是否存活的简单无操作查询。

若为空字符串,则禁用健康检查。

若为 <empty>,则发送空查询作为健康检查。

默认值:<empty>

server_fast_close

在会话池化模式下,如果服务端处于"close_needed"状态(由 RECONNECT、更改连接设置的 RELOAD 或 DNS 变更触发),则立即断开该服务端连接,或在当前事务结束后断开,而不是等到会话结束。在语句或事务池化模式下,此设置无效,因为那已经是默认行为。

如果因此设置导致服务端连接在客户端会话结束前被关闭,则客户端连接也会被关闭。这确保客户端注意到会话已被中断。

此设置使连接配置变更在使用会话池化和长时间会话时能更快生效。缺点是客户端会话可能因配置变更而被中断,因此客户端应用程序需要具备重连并重建会话状态的逻辑。但请注意,不会有任何事务丢失,因为正在运行的事务不会被中断,只有空闲会话才会被中断。

默认值:0

server_lifetime

连接池将关闭已建立连接时间超过此值的未使用服务端连接(即当前未与任何客户端连接关联的连接)。设为 0 表示连接只使用一次,然后关闭。[秒]

也可在 [databases] 节中按数据库设置。

默认值:3600.0

server_idle_timeout

如果服务端连接空闲超过此秒数,则关闭该连接。若为 0,则禁用此超时。[秒]

默认值:600.0

server_connect_timeout

如果连接和登录在此时间内未完成,则关闭该连接。[秒]

默认值:15.0

server_login_retry

如果因连接失败或认证失败导致无法登录到服务器,连接池在重试连接前等待的时间。在等待期间,尝试连接到故障服务器的新客户端将立即收到错误,而不会再次尝试连接。[秒]

此行为的目的是:当服务器不可用时,避免客户端不必要地排队等待服务端连接。但这也意味着,如果服务器出现短暂故障(例如在重启期间或配置有误时),连接池至少需要等待这么长时间才会再次考虑连接它。对于计划内的重启等事件,通常应使用 PAUSE 命令来管理,以避免此问题。

默认值:15.0

client_login_timeout

客户端连接后,若在此时间内未能完成登录,则断开该连接。主要用于避免僵尸连接阻塞 SUSPEND 进而影响在线重启。[秒]

默认值:60.0

autodb_idle_timeout

通过 * 自动创建的数据库连接池,若在此秒数内未被使用,则释放。其负面影响是对应的统计数据也会被清除。[秒]

默认值:3600.0

dns_max_ttl

DNS 查询结果可被缓存的时长。实际的 DNS TTL 值会被忽略。[秒]

默认值:15.0

dns_nxdomain_ttl

DNS 错误和 NXDOMAIN 查询结果可被缓存的时长。[秒]

默认值:15.0

dns_zone_check_period

检查区域序列号是否已变更的周期。

PgBouncer 可以从主机名(第一个点之后的所有内容)中收集 DNS 区域,并定期检查区域序列号是否变更。如果检测到变更,则重新查找该区域下的所有主机名。若任何主机的 IP 发生变化,则使相关连接失效。

仅适用于 c-ares 后端(configure 选项 --with-cares)。

默认值:0.0(禁用)

resolv_conf

自定义 resolv.conf 文件的位置。这允许独立于全局操作系统配置来指定自定义 DNS 服务器及其他名称解析选项。

需要 evdns(>= 2.0.3)或 c-ares(>= 1.15.0)后端。

文件的解析由 DNS 后端库完成,而非 PgBouncer,因此请参阅相应库的文档以了解允许的语法和指令。

默认值:空(使用操作系统默认值)

query_wait_notify

客户端在 PgBouncer 发送排队通知消息前等待的时间。[秒]

设为 0 时禁用此通知消息。

默认值:5


TLS 设置

如果任何证书或密钥文件的内容发生了变更,但配置中的文件名未变,新的文件内容将在 RELOAD 之后用于新的连接。但现有连接不会被关闭。如果出于安全原因需要让所有连接尽快使用新文件,建议在 RELOAD 之后运行 RECONNECT。

更改任何 TLS 设置都会出于安全原因自动触发 RECONNECT。

client_tls_sslmode

用于客户端连接的 TLS 模式。默认情况下禁用 TLS 连接。启用后,还必须配置 client_tls_key_fileclient_tls_cert_file,以设置 PgBouncer 用于接受客户端连接的密钥和证书。PgBouncer 支持的最常见证书文件格式是 PEM。

  • disable:纯 TCP 连接。若客户端请求 TLS,则忽略。默认值。
  • allow:若客户端请求 TLS,则使用 TLS;否则使用纯 TCP。若客户端提供了客户端证书,则不对其进行验证。
  • prefer:与 allow 相同。
  • require:客户端必须使用 TLS,否则拒绝连接。若客户端提供了客户端证书,则不对其进行验证。
  • verify-ca:客户端必须使用 TLS 并提供有效的客户端证书。
  • verify-full:与 verify-ca 相同。

client_tls_key_file

PgBouncer 用于接受客户端连接的私钥。

默认值:未设置

client_tls_cert_file

与私钥对应的证书,客户端可以对其进行验证。

默认值:未设置

client_tls_ca_file

用于验证客户端证书的根证书文件。

默认值:未设置

client_tls_protocols

允许使用的 TLS 协议版本。可选值:tlsv1.0tlsv1.1tlsv1.2tlsv1.3。快捷方式:all(tlsv1.0,tlsv1.1,tlsv1.2,tlsv1.3)、secure(tlsv1.2,tlsv1.3)。

默认值:secure

client_tls_ciphers

允许使用的 TLS 加密套件,采用 OpenSSL 语法。快捷方式:

  • default/secure/fast/normal(均使用系统级 OpenSSL 默认值)
  • all(启用所有加密套件,不推荐)

此设置仅影响使用 TLS 1.2 及以下版本的连接。目前没有用于控制 TLS 1.3 连接所使用加密套件的设置。

默认值:default

client_tls13_ciphers

允许使用的 TLS v1.3 加密套件。若为空,则使用 client_tls_ciphers 的值。可选值:

  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_GCM_SHA256
  • TLS_AES_128_CCM_8_SHA256
  • TLS_AES_128_CCM_SHA256

此设置仅影响使用 TLS 1.3 及以上版本的连接。对于 1.2 及以下版本,请参见 client_tls_ciphers

默认值:<empty>

client_tls_ecdhcurve

用于 ECDH 密钥交换的椭圆曲线名称。

可选值:none(禁用 DH)、auto(256 位 ECDH)、曲线名称

默认值:auto

client_tls_dheparams

DHE 密钥交换类型。

可选值:none(禁用 DH)、auto(2048 位 DH)、legacy(1024 位 DH)

默认值:auto

server_tls_sslmode

用于连接 PostgreSQL 服务器的 TLS 模式。默认模式为 prefer

  • disable:纯 TCP 连接。甚至不向服务器请求 TLS。
  • allow:待定:若服务器拒绝明文连接,则尝试 TLS?
  • prefer:始终首先向 PostgreSQL 请求 TLS 连接。若被拒绝,则通过纯 TCP 建立连接。不验证服务器证书。默认值。
  • require:连接必须使用 TLS。若服务器拒绝,则不尝试纯 TCP。不验证服务器证书。
  • verify-ca:连接必须使用 TLS,且服务器证书必须根据 server_tls_ca_file 有效。不检查服务器主机名与证书是否匹配。
  • verify-full:连接必须使用 TLS,且服务器证书必须根据 server_tls_ca_file 有效。服务器主机名必须与证书信息匹配。

server_tls_ca_file

用于验证 PostgreSQL 服务器证书的根证书文件。

默认值:未设置

server_tls_key_file

PgBouncer 用于向 PostgreSQL 服务器进行认证的私钥。

默认值:未设置

server_tls_cert_file

与私钥对应的证书,PostgreSQL 服务器可以对其进行验证。

默认值:未设置

server_tls_protocols

允许使用的 TLS 协议版本。可选值:tlsv1.0tlsv1.1tlsv1.2tlsv1.3。快捷方式:all(tlsv1.0,tlsv1.1,tlsv1.2,tlsv1.3)、secure(tlsv1.2,tlsv1.3)、legacy(all)。

默认值:secure

server_tls_ciphers

允许使用的 TLS 加密套件,采用 OpenSSL 语法。快捷方式:

  • default/secure/fast/normal(均使用系统级 OpenSSL 默认值)
  • all(启用所有加密套件,不推荐)

此设置仅影响使用 TLS 1.2 及以下版本的连接。目前没有用于控制 TLS 1.3 连接所使用加密套件的设置。

默认值:default

server_tls13_ciphers

允许使用的 TLS v1.3 加密套件。若为空,则使用 server_tls_ciphers 的值。可选值:

  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_GCM_SHA256
  • TLS_AES_128_CCM_8_SHA256
  • TLS_AES_128_CCM_SHA256

此设置仅影响使用 TLS 1.3 及以上版本的连接。对于 1.2 及以下版本,请参见 client_tls_ciphers

默认值:<empty>


危险超时

设置以下超时可能导致意外错误。

query_timeout

运行时间超过此值的查询将被取消。此设置应与略小于此值的服务端 statement_timeout 配合使用,以便仅针对网络问题生效。[秒]

默认值:0.0(禁用)

query_wait_timeout

查询等待执行的最长时间。若在此时间内未将查询分配给服务器,则断开客户端连接。0 表示禁用;禁用后,客户端将无限期排队。[秒]

此设置用于防止无响应的服务器占用连接。在服务器宕机或因任何原因拒绝连接时也有帮助。

默认值:120.0

cancel_wait_timeout

取消请求等待执行的最长时间。若在此时间内未将取消请求分配给服务器,则断开客户端连接。0 表示禁用;禁用后,取消请求将无限期排队。[秒]

此设置用于防止在服务器宕机导致取消请求无法转发时客户端被卡住。

默认值:10.0

client_idle_timeout

空闲时间超过此秒数的客户端连接将被关闭。此值应大于客户端侧的连接生命周期设置,且仅用于处理网络问题。[秒]

默认值:0.0(禁用)

idle_transaction_timeout

客户端处于"事务中空闲"状态超过此时间后,将被断开连接。[秒]

默认值:0.0(禁用)

transaction_timeout

客户端处于"事务进行中"状态超过此时间后,将被断开连接。[秒]

默认值:0.0(禁用)

suspend_timeout

SUSPEND 或重启(-R)期间,等待缓冲区刷新的时长。若刷新未能成功完成,则断开该连接。[秒]

默认值:10


底层网络设置

pkt_buf

数据包的内部缓冲区大小,影响发送的 TCP 数据包大小和总体内存使用量。实际的 libpq 数据包可能大于此值,因此无需将其设置得很大。

默认值:4096

max_packet_size

PgBouncer 允许通过的 PostgreSQL 数据包的最大大小。一个数据包对应一条查询或一行结果集,完整的结果集可以更大。

默认值:2147483647

listen_backlog

listen(2) 的 backlog 参数,决定在队列中保留多少个未应答的新连接尝试。队列满时,后续新连接将被丢弃。

默认值:128

sbuf_loopcnt

在继续处理之前,对单个连接上的数据进行多少轮处理。若没有此限制,一个拥有大型结果集的连接可能会长时间阻塞 PgBouncer。每轮处理一个 pkt_buf 大小的数据量。0 表示不限制。

默认值:5

so_reuseport

指定是否在 TCP 监听套接字上设置 SO_REUSEPORT 套接字选项。在某些操作系统上,这允许在同一主机上运行多个 PgBouncer 实例,监听相同端口,并由内核自动分配连接。此选项是让 PgBouncer 使用更多 CPU 核心的一种方式。(PgBouncer 是单线程的,每个实例使用一个 CPU 核心。)

具体行为取决于操作系统内核。截至本文撰写时,此设置在(足够新版本的)Linux、DragonFlyBSD 和 FreeBSD 上具有预期效果(在 FreeBSD 上,应用的是 SO_REUSEPORT_LB 套接字选项)。某些其他操作系统支持该套接字选项,但不会达到预期效果:允许多个进程绑定到同一端口,但只有其中一个会收到连接。详情请参阅操作系统的 setsockopt() 文档。

在完全不支持该套接字选项的系统上,启用此设置将导致错误。

同一主机上的每个 PgBouncer 实例至少需要为 unix_socket_dirpidfile 配置不同的值,如果使用 logfile 也是如此。另外请注意,如果使用了此选项,就无法再通过 TCP/IP 连接到特定的 PgBouncer 实例,这可能对监控和指标收集有影响。

为确保查询取消功能正常工作,应在不同的 PgBouncer 进程之间配置 PgBouncer 对等(peering)。详情请参阅 peer_id 配置选项和 peers 配置节的文档。本文档示例节中也提供了一个使用对等和 so_reuseport 的示例。

默认值:0

tcp_defer_accept

设置 TCP_DEFER_ACCEPT 套接字选项;详见 man 7 tcp。(这是一个布尔选项:1 表示启用。启用时实际设置的值当前硬编码为 45 秒。)

目前仅在 Linux 上支持。

默认值:Linux 上为 1,其他系统为 0

tcp_socket_buffer

默认值:未设置

tcp_keepalive

使用操作系统默认值开启基本的 keepalive。

在 Linux 上,系统默认值为 tcp_keepidle=7200tcp_keepintvl=75tcp_keepcnt=9。其他操作系统上的默认值可能相近。

默认值:1

tcp_keepcnt

默认值:未设置

tcp_keepidle

默认值:未设置

tcp_keepintvl

默认值:未设置

tcp_user_timeout

设置 TCP_USER_TIMEOUT 套接字选项。该选项指定已传输数据在 TCP 连接被强制关闭之前,可以保持未确认状态的最长时间(毫秒)。若设为 0,则使用操作系统默认值。

目前仅在 Linux 上支持。

默认值:0


[databases] 节

[databases] 节定义了 PgBouncer 客户端可以连接的数据库名称,并指定这些连接将被路由到何处。该节包含如下形式的 key=value 行:

dbname = connection string

其中键将作为数据库名称,值将作为连接字符串,由以下描述的连接参数键值对组成(类似于 libpq,但实际上并不使用 libpq,且可用功能集有所不同)。示例:

foodb = host=host1.example.com port=5432
bardb = host=localhost dbname=bazdb

数据库名称可包含字符 _0-9A-Za-z 而无需引号。包含其他字符的名称需要使用标准 SQL 标识符引号(双引号)括起来,双引号字符本身用 "" 表示。

数据库名称 pgbouncer 为管理控制台保留,不能在此处用作键。

* 充当后备数据库:若请求的数据库名称不完全匹配任何条目,则将其值作为所请求数据库的连接字符串使用。例如,若存在(且没有其他覆盖条目):

* = host=foo

那么,指定数据库 bar 连接到 PgBouncer 时,其行为实际上等同于存在如下条目:

bar = host=foo dbname=bar

(利用了 dbname 默认为客户端侧数据库名的特性;见下文。)

此类自动创建的数据库条目,若空闲时间超过 autodb_idle_timeout 参数指定的时间,则会被清除。

dbname

目标数据库名称。

默认值:与客户端侧数据库名相同

host

连接的目标主机名或 IP 地址。主机名在连接时解析,结果按 dns_max_ttl 参数进行缓存。当主机名的解析结果发生变化时,现有服务端连接在被释放时(根据池化模式)自动关闭,新的服务端连接立即使用新的解析结果。若 DNS 返回多个结果,则以轮询方式使用。

若值以 / 开头,则使用文件系统命名空间中的 Unix 套接字。若以 @ 开头,则使用抽象命名空间中的 Unix 套接字。

可以指定逗号分隔的主机名或地址列表,连接将以轮询方式建立。(若主机列表中的主机名通过 DNS 解析到多个地址,则轮询系统独立运行。这是一个实现细节,可能会发生变化。)注意,列表中所有主机在任何时候都必须可用:没有跳过不可达主机或仅选择可用主机的机制。(这与 libpq 中主机列表的含义不同。)另外请注意,这只影响新连接的目标选择方式。关于客户端如何被分配到已建立的服务端连接,另见 server_round_robin 设置。

示例:

host=localhost
host=127.0.0.1
host=2001:0db8:85a3:0000:0000:8a2e:0370:7334
host=/var/run/postgresql
host=192.168.0.1,192.168.0.2,192.168.0.3

默认值:未设置,表示使用 Unix 套接字

port

默认值:5432

user

若设置了 user=,则所有到目标数据库的连接都将以指定用户进行,意味着该数据库只有一个连接池。

否则,PgBouncer 将以客户端用户名登录到目标数据库,意味着每个用户有一个连接池。

password

若此处未指定密码,则使用 auth_file 中对应上述指定用户的密码。目前不支持动态密码发现方式(如 auth_query)。

auth_user

若指定,则覆盖全局 auth_user 设置。

auth_query

若指定,则覆盖全局 auth_query 设置。整个 SQL 语句需要用单引号括起来。

auth_dbname

若指定,则覆盖全局 auth_dbname 设置。

pool_size

设置此数据库的连接池最大大小。若未设置,则使用 default_pool_size

min_pool_size

设置此数据库的连接池最小大小。若未设置,则使用全局 min_pool_size

仅在以下至少一个条件满足时才强制执行:

  • [database] 节中此条目设置了 user 键(即强制用户)
  • 该连接池中至少有一个客户端连接

reserve_pool_size

为此数据库设置额外连接数。若未设置,则使用全局 reserve_pool_size。出于向后兼容原因,reserve_pool 是此选项的别名。

connect_query

连接建立后、允许任何客户端使用该连接前执行的查询。若查询引发错误,则记录日志但忽略该错误。

pool_mode

为此数据库设置特定的池化模式。若未设置,则使用默认的 pool_mode

load_balance_hosts

host 中指定了逗号分隔的列表时,load_balance_hosts 控制新连接选择哪个条目。

注意:此设置目前仅控制在连接字符串中提供多个主机时的负载均衡行为,不控制单个主机的 DNS 记录指向多个 IP 地址的情况。这是一个待实现的功能,因此在未来版本中此设置可能开始同时控制这两种负载均衡方式。

  • round-robin:新的连接尝试选择列表中的下一个主机条目。
  • disable:新的连接继续使用同一主机条目,直到连接失败,之后选择下一个主机条目。

建议将 server_login_retry 设置得低于默认值,以确保在有多个可用主机时能快速重试。

默认值:round-robin

max_db_connections

配置该数据库的服务端连接上限(即该数据库内所有连接池的服务端连接总数不超过此值)。

max_db_client_connections

配置该数据库的客户端连接上限。应与 max_client_conn 配合使用,以限制 PgBouncer 允许接受的连接数。

server_lifetime

按数据库配置 server_lifetime。若未设置,则回退到实例级别配置的 server_lifetime

client_encoding

向服务器请求特定的 client_encoding

datestyle

向服务器请求特定的 datestyle

timezone

向服务器请求特定的 timezone


[users] 节

本节包含如下形式的 key=value 行:

user1 = settings

其中键将作为用户名,值将作为该用户特定配置设置的键值对列表。示例:

user1 = pool_mode=session

此处仅支持少数几项设置。

注意:当配置了 auth_file 时,若某用户在本节中有定义但未列于 auth_file 中,且已设置 auth_user,则 PgBouncer 将尝试使用 auth_query 为该用户查找密码。若未设置 auth_user,PgBouncer 将假装该用户存在,但不会向客户端返回"无此用户"消息,也不会接受任何提供的密码。

pool_size

设置此用户所有连接的连接池最大大小。若未设置,则使用数据库级别或 default_pool_size

reserve_pool_size

设置允许为此用户连接池添加的额外连接数。若未设置,则使用数据库级别配置或全局 reserve_pool_size

pool_mode

设置此用户所有连接使用的池化模式。若未设置,则使用数据库级别或默认的 pool_mode

max_user_connections

配置该用户的服务端连接上限(即该用户的所有连接池的服务端连接总数不超过此值)。

query_timeout

设置用户查询的最长运行秒数。若设置,此超时将覆盖上述服务器级别的 query_timeout

idle_transaction_timeout

设置用户保持事务空闲打开的最长秒数。若设置,此超时将覆盖上述服务器级别的 idle_transaction_timeout

transaction_timeout

设置用户保持事务打开的最长秒数。若设置,此超时将覆盖上述服务器级别的 transaction_timeout

client_idle_timeout

设置客户端在 PgBouncer 实例上保持空闲连接的最长秒数。若设置,此超时将覆盖上述服务器级别的 client_idle_timeout

请注意,这是一个潜在危险的超时。

max_user_client_connections

配置该用户的客户端连接上限。这是 max_client_conn 设置在用户级别的等效项。


[peers] 节

[peers] 节定义了 PgBouncer 可以将取消请求转发到的对等节点,以及这些取消请求将被路由到的位置。

可以通过在所有 PgBouncer 进程的配置中定义 peer_id 值和 [peers] 节,将多个 PgBouncer 进程组成一组对等节点。这些 PgBouncer 进程可以将取消请求转发到其来源进程。当多个 PgBouncer 进程(可能在不同服务器上)位于同一 TCP 负载均衡器后端时,这对于使取消功能正常工作是必要的。取消请求通过与被取消查询不同的 TCP 连接发送,因此 TCP 负载均衡器可能会将取消请求连接发送到与预期不同的进程。通过配置对等关系,这些取消请求最终会到达正确的进程。这份 会议演讲录像 提供了更深入的解释。

本节包含如下形式的 key=value 行:

peer_id = connection string

其中键将作为 peer_id,值将作为连接字符串,由以下描述的连接参数键值对组成(类似于 libpq,但实际上并不使用 libpq,且可用功能集有所不同)。示例:

1 = host=host1.example.com
2 = host=/tmp/pgbouncer-2  port=5555

注意 1:要使对等功能正常工作,组内每个 PgBouncer 进程的 peer_id 在对等组中必须唯一。且 [peers] 节应包含所有这些对等 ID 的条目。文档示例节中有一个示例。允许(但非必须)[peers] 节包含当前配置所属 PgBouncer 的 peer_id,此类条目会被忽略,但允许这样做是为了便于配置管理——使得同一个 [peers] 节可以用于多个配置文件。

注意 2:只要所有对等节点都在 v1.21.0 版本边界的同一侧,即支持跨版本对等。v1.21.0 对取消令牌的编码方式做了一些破坏性变更,与早期版本不兼容。

host

连接的目标主机名或 IP 地址。主机名在连接时解析,结果按 dns_max_ttl 参数进行缓存。若 DNS 返回多个结果,则以轮询方式使用。但一般不建议使用解析到多个 IP 的主机名,因为这样取消请求可能仍会被转发到错误的节点,需要再次转发(最多只允许转发三次)。

若值以 / 开头,则使用文件系统命名空间中的 Unix 套接字。若以 @ 开头,则使用抽象命名空间中的 Unix 套接字。

示例:

host=localhost
host=127.0.0.1
host=2001:0db8:85a3:0000:0000:8a2e:0370:7334
host=/var/run/pgbouncer-1

port

默认值:6432

pool_size

设置同时发往该对等节点的最大在途取消请求数。取消请求以突发形式到达是很常见的,例如当后端 Postgres 服务器响应缓慢或宕机时。因此,pool_size 不应设置得太低而无法处理这些突发请求。

若未设置,则使用 default_pool_size


Include 指令

PgBouncer 配置文件可以包含 include 指令,用于指定要读取和处理的另一个配置文件。这允许将配置文件拆分为物理上独立的部分。include 指令的格式如下:

%include filename

若文件名不是绝对路径,则相对于当前工作目录进行解析。


认证文件格式

本节描述 auth_file 设置所指定文件的格式。该文件是如下格式的文本文件:

"username1" "password" ...
"username2" "md5abcdef012342345" ...
"username2" "SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>"

至少需要 2 个字段,并用双引号括起。第一个字段是用户名,第二个字段是明文密码、MD5 哈希密码或 SCRAM 密钥。PgBouncer 忽略该行的其余内容。字段值中的双引号可以用两个双引号来转义。

PostgreSQL MD5 哈希密码格式:

"md5" + md5(password + username)

因此,用户名为 admin、密码为 1234 的用户,其 MD5 哈希密码为 md545f2603610af569b6155c45067268c6b

PostgreSQL SCRAM 密钥格式:

SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>

详情请参见 PostgreSQL 文档和 RFC 5803。

认证文件中存储的密码或密钥有两个用途:一是在配置了基于密码的认证方式时,用于验证传入客户端连接的密码;二是在后端服务器需要基于密码认证时,用作到后端服务器出站连接的密码(除非在数据库的连接字符串中直接指定了密码)。

限制

若密码以明文存储,则可用于后端服务器使用的任何基于密码的认证方式:明文、MD5 或 SCRAM(详见 https://www.postgresql.org/docs/current/auth-password.html)。

MD5 哈希密码可用于后端服务器使用 MD5 认证(或特定用户具有 MD5 哈希密码)的情况。

SCRAM 密钥只有在以下条件同时满足时才能用于登录服务器:客户端认证也使用 SCRAM;PgBouncer 数据库定义中未指定用户名;且 PgBouncer 与 PostgreSQL 服务器中的 SCRAM 密钥完全相同(相同的盐值和迭代次数,而不仅仅是相同的密码)。这是由 SCRAM 固有的安全属性决定的:存储的 SCRAM 密钥本身不能用于推导登录凭据。

认证文件可以手动编写,但也可以从其他用户和密码列表生成。参见 ./etc/mkauth.py 了解从 pg_authid 系统表生成认证文件的示例脚本。也可以使用 auth_query 代替 auth_file,以避免维护单独的认证文件。

关于托管服务器的说明

若后端服务器配置为使用 SCRAM 密码认证,且 PgBouncer 不知道用户的明文密码或对应的 SCRAM 密钥,则 PgBouncer 无法成功认证。

某些云服务提供商(如 AWS RDS)禁止访问 PostgreSQL 敏感系统表以获取密码。即使是权限最高的用户(如 rds_superuser 的成员),执行 select * from pg_authid 也会返回 ERROR: permission denied for table pg_authid。这是已知行为(博客)。

因此,在托管服务器中一旦存储了 SCRAM 密钥,便无法再获取,这使得配置 PgBouncer 使用相同 SCRAM 密钥变得困难。不过,仍然可以通过以下技巧在双方配置并使用 SCRAM 密钥:

使用能够打印出密钥的工具为任意密码生成 SCRAM 密钥。例如,psql --echo-hidden\password 命令会在将 SCRAM 密钥发送到服务器之前将其打印到控制台。

$ psql --echo-hidden <connection_string>
postgres=# \password <role_name>
Enter new password for user "<role_name>":
Enter it again:
********* QUERY **********
ALTER USER <role_name> PASSWORD 'SCRAM-SHA-256$<iterations>:<salt>$<storedkey>:<serverkey>'
**************************

记下 QUERY 中的 SCRAM 密钥,并将其设置到 PgBouncer 的 userlist.txt 中。

若使用了 psql --echo-hidden 以外的工具,则还需要在服务器端设置 SCRAM 密钥(可以使用 ALTER ROLE <role_name> PASSWORD '<scram_secret>' 来设置)。


HBA 文件格式

HBA 文件的位置由 auth_hba_file 设置指定。仅当 auth_type 设置为 hba 时才使用。

该文件遵循 PostgreSQL pg_hba.conf 文件的格式(见 https://www.postgresql.org/docs/current/auth-pg-hba-conf.html)。

  • 支持的记录类型:localhosthostsslhostnossl
  • 数据库字段:支持 allreplicationsameuser@file、多个名称。不支持:samerolesamegroup
  • 用户名字段:支持 all@file、多个名称。不支持:+groupname
  • 地址字段:支持 all、IPv4、IPv6。不支持:samehostsamenet、DNS 名称、域前缀。
  • 认证方式字段:仅支持 PgBouncer auth_type 支持的方式,以及 peerreject,但不支持 anypam(它们只在全局范围内有效)。
  • auth_typecertpeer 时,支持用户名映射(map=)参数。

Ident 映射文件格式

Ident 映射文件的位置由 auth_ident_file 设置指定。仅当 auth_type 设置为 hba 时才加载。

该文件格式是 PostgreSQL ident 映射文件的简化变体(见 https://www.postgresql.org/docs/current/auth-username-maps.html)。

  • 支持的行格式仅为 map-name system-username database-username
  • 不支持 include 文件/目录。
  • 系统用户名字段:不支持正则表达式。
  • 数据库用户名字段:支持 all 或单个 Postgres 用户名。不支持:+groupname、正则表达式。

示例

小型配置示例:

[databases]
template1 = host=localhost dbname=template1 auth_user=someuser

[pgbouncer]
pool_mode = session
listen_port = 6432
listen_addr = localhost
auth_type = md5
auth_file = users.txt
logfile = pgbouncer.log
pidfile = pgbouncer.pid
admin_users = someuser
stats_users = stat_collector

数据库配置示例:

[databases]

; foodb 通过 Unix 套接字连接
foodb =

; 将 bardb 重定向到 localhost 上的 bazdb
bardb = host=localhost dbname=bazdb

; 到目标数据库的访问将以单一用户进行
forcedb = host=localhost port=300 user=baz password=foo client_encoding=UNICODE datestyle=ISO

auth_query 安全函数示例:

CREATE OR REPLACE FUNCTION pgbouncer.user_lookup(in i_username text, out uname text, out phash text)
RETURNS record AS $$
BEGIN
    SELECT rolname, CASE WHEN rolvaliduntil < now() THEN NULL ELSE rolpassword END
    FROM pg_authid
    WHERE rolname=i_username AND rolcanlogin
    INTO uname, phash;
    RETURN;
END;
$$ LANGUAGE plpgsql
   SECURITY DEFINER
   -- 设置安全的 search_path:受信任的模式,然后是 'pg_temp'。
   SET search_path = pg_catalog, pg_temp;
REVOKE ALL ON FUNCTION pgbouncer.user_lookup(text) FROM public, pgbouncer;
GRANT EXECUTE ON FUNCTION pgbouncer.user_lookup(text) TO pgbouncer;

使用 so_reuseport 配置 2 个对等 PgBouncer 进程以创建多核 PgBouncer 部署的配置示例。第一个进程的配置:

[databases]
postgres = host=localhost dbname=postgres

[peers]
1 = host=/tmp/pgbouncer1
2 = host=/tmp/pgbouncer2

[pgbouncer]
listen_addr=127.0.0.1
auth_file=auth_file.conf
so_reuseport=1
unix_socket_dir=/tmp/pgbouncer1
peer_id=1

第二个进程的配置:

[databases]
postgres = host=localhost dbname=postgres

[peers]
1 = host=/tmp/pgbouncer1
2 = host=/tmp/pgbouncer2

[pgbouncer]
listen_addr=127.0.0.1
auth_file=auth_file.conf
so_reuseport=1
; 只有 unix_socket_dir 和 peer_id 不同
unix_socket_dir=/tmp/pgbouncer2
peer_id=2

另请参阅

pgbouncer(1) - 通用用法及控制台命令的 man 手册页

3 - pgbouncer 命令用法

PgBouncer 命令行用法与管理控制台

原始页面: https://www.pgbouncer.org/usage.html


语法

pgbouncer [-d][-R][-v][-u user] <pgbouncer.ini>
pgbouncer -V|-h

在 Windows 系统上,选项如下:

pgbouncer.exe [-v][-u user] <pgbouncer.ini>
pgbouncer.exe -V|-h

用于设置 Windows 服务的附加选项:

pgbouncer.exe --regservice   <pgbouncer.ini>
pgbouncer.exe --unregservice <pgbouncer.ini>

描述

pgbouncer 是一个 PostgreSQL 连接池。任何目标应用程序都可以像连接 PostgreSQL 服务器一样连接到 pgbouncerpgbouncer 会创建一个到实际服务器的连接,或者复用已有连接。

pgbouncer 的目标是降低向 PostgreSQL 打开新连接所带来的性能损耗。

为了在连接池化时不破坏事务语义,pgbouncer 在轮换连接时支持以下几种池化模式:

会话池化

最保守的方式。当客户端连接时,将为其分配一个服务端连接,并在客户端保持连接期间一直持有。当客户端断开时,该服务端连接将被归还到连接池中。这是默认模式。

事务池化

仅在事务期间将服务端连接分配给客户端。当 PgBouncer 检测到事务结束后,该服务端连接将被归还到连接池中。

语句池化

最激进的方式。查询完成后,服务端连接将立即归还到连接池中。此模式下不允许多语句事务,因为这会导致错误。

pgbouncer 的管理接口由一些新的 SHOW 命令组成,这些命令在连接到特殊的"虚拟"数据库 pgbouncer 时可用。


快速入门

基本的安装和使用步骤如下。

  1. 创建 pgbouncer.ini 文件。详见 pgbouncer(5)。简单示例:

     [databases]
     template1 = host=localhost port=5432 dbname=template1
    
     [pgbouncer]
     listen_port = 6432
     listen_addr = localhost
     auth_type = md5
     auth_file = userlist.txt
     logfile = pgbouncer.log
     pidfile = pgbouncer.pid
     admin_users = someuser
    
  2. 创建 userlist.txt 文件,其中包含允许登录的用户:

     "someuser" "same_password_as_in_server"
    
  3. 启动 pgbouncer

     $ pgbouncer -d pgbouncer.ini
    
  4. 让应用程序(或 psql 客户端)连接到 pgbouncer 而不是直接连接到 PostgreSQL 服务器:

     $ psql -p 6432 -U someuser template1
    
  5. 通过连接到特殊管理数据库 pgbouncer 来管理 pgbouncer,并执行 SHOW HELP; 开始操作:

     $ psql -p 6432 -U someuser pgbouncer
     pgbouncer=# SHOW HELP;
     NOTICE:  Console usage
     DETAIL:
       SHOW [HELP|CONFIG|DATABASES|FDS|POOLS|CLIENTS|SERVERS|SOCKETS|LISTS|VERSION|...]
       SET key = arg
       RELOAD
       PAUSE
       SUSPEND
       RESUME
       SHUTDOWN
       [...]
    
  6. 如果对 pgbouncer.ini 文件进行了修改,可以通过以下命令重新加载:

     pgbouncer=# RELOAD;
    

命令行选项

-d--daemon
在后台运行。不加此选项时,进程将在前台运行。

在守护进程模式下,需要同时设置 pidfile 以及 logfilesyslog。进入后台后,不会向 stderr 写入任何日志信息。

注意:在 Windows 上不可用;pgbouncer 需要以服务形式运行。

-R--reboot
已弃用:请使用多个 pgbouncer 进程通过 so_reuseport 监听同一端口的滚动重启方式来替代此选项。 执行在线重启。即连接到正在运行的进程,从中加载已打开的套接字,然后使用这些套接字。如果没有活动进程,则正常启动。 注意:仅在 OS 支持 Unix 套接字且配置中未禁用 unix_socket_dir 时有效。在 Windows 上不可用。TLS 连接不兼容此选项,将被断开。
-u USERNAME--user=USERNAME
启动时切换到指定用户。
-v--verbose
增加详细程度。可多次使用。
-q--quiet
静默模式:不向 stderr 输出日志。这不影响日志详细程度,仅禁止使用 stderr。适用于 init.d 脚本。
-V--version
显示版本信息。
-h--help
显示简短帮助信息。
--regservice
Win32:将 PgBouncer 注册为 Windows 服务。使用配置参数 service_name 的值作为注册名称。
--unregservice
Win32:注销 Windows 服务。

管理控制台

通过普通方式连接到数据库 pgbouncer 即可访问控制台:

$ psql -p 6432 pgbouncer

只有在配置参数 admin_usersstats_users 中列出的用户才能登录控制台。(当 auth_type=any 时,任何用户均可作为 stats_user 登录。)

此外,用户名为 pgbouncer 的用户可以无密码登录,前提是通过 Unix 套接字连接,且客户端的 Unix 用户 UID 与运行进程相同。

管理控制台目前仅支持简单查询协议。部分驱动程序对所有命令使用扩展查询协议,这些驱动程序无法用于此目的。

Show 命令

SHOW 命令用于输出信息,每个命令说明如下。

SHOW STATS

显示统计信息。在此命令及相关命令中,总计数据自进程启动起累计,平均值每隔 stats_period 更新一次。

database
统计信息按数据库呈现。
total_xact_count
pgbouncer 处理的 SQL 事务总数。
total_query_count
pgbouncer 处理的 SQL 命令总数。
total_server_assignment_count
服务端连接被分配给客户端的总次数。
total_received
pgbouncer 接收的网络流量总字节数。
total_sent
pgbouncer 发送的网络流量总字节数。
total_xact_time
pgbouncer 连接到 PostgreSQL 并处于事务中(包括事务空闲或执行查询)所花费的总微秒数。
total_query_time
pgbouncer 主动连接到 PostgreSQL 并执行查询所花费的总微秒数。
total_wait_time
客户端等待服务端连接所花费的总时间(微秒)。在客户端连接被分配到后端连接时更新。
total_client_parse_count
客户端创建的预处理语句总数。仅适用于命名预处理语句跟踪模式,参见 max_prepared_statements
total_server_parse_count
pgbouncer 在服务端创建的预处理语句总数。仅适用于命名预处理语句跟踪模式,参见 max_prepared_statements
total_bind_count
客户端准备执行并由 pgbouncer 转发给 PostgreSQL 的预处理语句总数。仅适用于命名预处理语句跟踪模式,参见 max_prepared_statements
avg_xact_count
最近统计周期内每秒平均事务数。
avg_query_count
最近统计周期内每秒平均查询数。
avg_server_assignment_count
最近统计周期内每秒平均服务端连接分配次数。
avg_recv
每秒平均接收(来自客户端)字节数。
avg_sent
每秒平均发送(到客户端)字节数。
avg_xact_time
平均事务持续时间(微秒)。
avg_query_time
平均查询持续时间(微秒)。
avg_wait_time
客户端等待服务端的时间(微秒),为当前 stats_period 内被分配到后端的客户端等待时间的平均值。
avg_client_parse_count
客户端创建预处理语句的平均数量。仅适用于命名预处理语句跟踪模式,参见 max_prepared_statements
avg_server_parse_count
pgbouncer 在服务端创建预处理语句的平均数量。仅适用于命名预处理语句跟踪模式,参见 max_prepared_statements
avg_bind_count
客户端准备执行并由 pgbouncer 转发给 PostgreSQL 的预处理语句平均数量。仅适用于命名预处理语句跟踪模式,参见 max_prepared_statements

SHOW STATS_TOTALS

SHOW STATS 的子集,仅显示总计值(total_ 前缀字段)。

SHOW STATS_AVERAGES

SHOW STATS 的子集,仅显示平均值(avg_ 前缀字段)。

SHOW TOTALS

类似 SHOW STATS,但跨所有数据库汇总。

SHOW SERVERS

type
S,表示服务端。
user
pgbouncer 用于连接服务端的用户名。
database
数据库名称。
replication
服务端连接是否使用复制。可为 nonelogicalphysical
state
PgBouncer 服务端连接的状态,为以下之一:activeidleusedtestednewactive_cancelbeing_canceled
addr
PostgreSQL 服务器的 IP 地址。
port
PostgreSQL 服务器的端口。
local_addr
本机上连接的起始地址。
local_port
本机上连接的起始端口。
connect_time
连接建立的时间。
request_time
最近一次请求发出的时间。
wait
服务端连接不使用此字段。
wait_us
服务端连接不使用此字段。
close_needed
若为 1,表示该连接将尽快关闭,原因是配置文件重新加载或 DNS 更新改变了连接信息,或发出了 RECONNECT 命令。
ptr
此连接内部对象的地址。
link
与该服务端配对的客户端连接地址。
remote_pid
后端服务器进程的 PID。若连接通过 Unix 套接字建立且 OS 支持获取进程 ID 信息,则为 OS PID;否则从服务器发送的取消包中提取,对于 PostgreSQL 服务器应为 PID,对于另一个 PgBouncer 则为随机数。
tls
TLS 连接信息字符串,未使用 TLS 时为空。
application_name
链接客户端连接上设置的 application_name 字符串,未设置或无链接连接时为空。
prepared_statements
服务端上已准备的预处理语句数量,受 max_prepared_statements 设置限制。
id
服务端的唯一 ID。

SHOW CLIENTS

type
C,表示客户端。
user
客户端连接使用的用户名。
database
数据库名称。
replication
客户端连接是否使用复制。可为 nonelogicalphysical
state
客户端连接的状态,为以下之一:active(已链接到服务端连接的客户端)、idle(无等待查询的空闲客户端)、waitingactive_cancel_reqwaiting_cancel_req
addr
客户端的 IP 地址。
port
客户端的源端口。
local_addr
本机上连接的终止地址。
local_port
本机上连接的终止端口。
connect_time
连接时间的时间戳。
request_time
最近一次客户端请求的时间戳。
wait
当前等待时间(秒)。
wait_us
当前等待时间的微秒部分。
close_needed
客户端不使用此字段。
ptr
此连接内部对象的地址。
link
与该客户端配对的服务端连接地址。
remote_pid
进程 ID,当客户端通过 Unix 套接字连接且 OS 支持获取时可用。
tls
TLS 连接信息字符串,未使用 TLS 时为空。
application_name
客户端为此连接设置的 application_name 字符串,未设置时为空。
prepared_statements
客户端已准备的预处理语句数量。
id
客户端的唯一 ID。

SHOW POOLS

每对(database,user)组合会创建一个连接池条目。

database
数据库名称。
user
用户名。
cl_active
已链接到服务端连接或空闲无等待查询的客户端连接数。
cl_waiting
已发送查询但尚未获得服务端连接的客户端连接数。
cl_active_cancel_req
已将查询取消请求转发给服务端并等待服务端响应的客户端连接数。
cl_waiting_cancel_req
尚未将查询取消请求转发给服务端的客户端连接数。
sv_active
已链接到客户端的服务端连接数。
sv_active_cancel
当前正在转发取消请求的服务端连接数。
sv_being_canceled
正常情况下可变为空闲,但正在等待所有发送到该服务端以取消查询的飞行中取消请求完成后才能变为空闲的服务端连接数。
sv_idle
未使用且可立即用于客户端查询的服务端连接数。
sv_used
空闲时间超过 server_check_delay 的服务端连接数,需要先运行 server_check_query 才能再次使用。
sv_tested
当前正在运行 server_reset_queryserver_check_query 的服务端连接数。
sv_login
当前正在登录过程中的服务端连接数。
maxwait
队列中第一个(最早的)客户端已等待的时间(秒)。若此值持续增加,说明当前服务端连接池处理请求的速度不够快,原因可能是服务器过载或 pool_size 设置过小。
maxwait_us
最大等待时间的微秒部分。
pool_mode
当前使用的池化模式。
load_balance_hosts
若连接池的 host 包含逗号分隔列表,则显示所使用的 load_balance_hosts。

SHOW PEER_POOLS

每个已配置的 peer 会创建一个 peer_pool 条目。

database
已配置 peer 条目的 ID。
cl_active_cancel_req
已将查询取消请求转发给服务端并等待服务端响应的客户端连接数。
cl_waiting_cancel_req
尚未将查询取消请求转发给服务端的客户端连接数。
sv_active_cancel
当前正在转发取消请求的服务端连接数。
sv_login
当前正在登录过程中的服务端连接数。

SHOW LISTS

以列(而非行)形式显示以下内部信息:

databases
数据库数量。
users
用户数量。
pools
连接池数量。
free_clients
空闲客户端数量。这些客户端已断开连接,但 PgBouncer 保留了为其分配的内存,以便后续客户端复用,避免重复分配。
used_clients
已使用的客户端数量。
login_clients
处于 login 状态的客户端数量。
free_servers
空闲服务端数量。这些服务端已断开连接,但 PgBouncer 保留了为其分配的内存,以便后续服务端复用,避免重复分配。
used_servers
已使用的服务端数量。
dns_names
DNS 缓存中的域名数量。
dns_zones
DNS 缓存中的 DNS 区域数量。
dns_queries
飞行中的 DNS 查询数量。
dns_pending
未使用。

SHOW USERS

name
用户名。
pool_size
用户的覆盖 pool_size,未设置则为 NULL。
reserve_pool_size
用户的覆盖 reserve_pool_size,未设置则为 NULL。
pool_mode
用户的覆盖 pool_mode,未设置则为 NULL。
max_user_connections
用户的 max_user_connections 设置。若未为该用户单独设置,则显示默认值。
current_connections
该用户当前向所有服务器打开的服务端连接数。
max_user_client_connections
用户的 max_user_client_connections 设置。若未为该用户单独设置,则显示默认值。
current_client_connections
该用户当前向 PgBouncer 打开的客户端连接数。

SHOW DATABASES

name
已配置数据库条目的名称。
host
PgBouncer 连接到的主机。
port
PgBouncer 连接到的端口。
database
PgBouncer 实际连接到的数据库名称。
force_user
当用户包含在连接字符串中时,无论客户端用户是谁,PgBouncer 与 PostgreSQL 之间的连接都强制使用指定用户。
pool_size
最大服务端连接数。
min_pool_size
最小服务端连接数。
reserve_pool_size
此数据库的最大附加连接数。
server_lifetime
此数据库服务端连接的最大生命周期。
pool_mode
数据库的覆盖 pool_mode,为 NULL 时使用默认值。
load_balance_hosts
若 host 包含逗号分隔列表,则显示数据库的 load_balance_hosts。
max_connections
此数据库允许的最大服务端连接数,由 max_db_connections 全局或按数据库设置。
current_connections
此数据库当前的服务端连接数。
max_client_connections
此 PgBouncer 实例允许的最大客户端连接数,由 max_db_client_connections 按数据库设置。
current_client_connections
此数据库当前的客户端连接数。
paused
若此数据库当前已暂停则为 1,否则为 0。
disabled
若此数据库当前已禁用则为 1,否则为 0。

SHOW PEERS

peer_id
已配置 peer 条目的 ID。
host
PgBouncer 连接到的主机。
port
PgBouncer 连接到的端口。
pool_size
可向此 peer 建立的最大服务端连接数。

SHOW FDS

内部命令——显示当前使用中的文件描述符列表及其关联的内部状态。

当连接用户名为"pgbouncer"、通过 Unix 套接字连接且 UID 与运行进程相同时,实际的 FD 将通过连接传递。此机制用于在线重启。 注意:在 Windows 上不可用。

此命令还会阻塞内部事件循环,因此在 PgBouncer 使用期间不应调用。

fd
文件描述符的数值。
task
poolerclientserver 之一。
user
使用该 FD 的连接的用户名。
database
使用该 FD 的连接的数据库名。
addr
使用该 FD 的连接的 IP 地址,若使用 Unix 套接字则为 unix
port
使用该 FD 的连接所用的端口。
cancel
此连接的取消密钥。
link
对应服务端/客户端的 FD。空闲时为 NULL。

SHOW SOCKETS, SHOW ACTIVE_SOCKETS

显示套接字或仅显示活跃套接字的底层信息。包含 SHOW CLIENTSSHOW SERVERS 所显示的信息,以及其他更底层的信息。

SHOW CONFIG

显示当前配置设置,每行一条,包含以下列:

key
配置变量名称。
value
配置值。
default
配置默认值。
changeable
yesno,表示该变量是否可在运行时更改。若为 no,则只能在启动时更改。使用 SET 在运行时更改变量。

SHOW MEM

显示各种内部内存分配当前大小的底层信息。所呈现的信息可能随版本变化。

SHOW DNS_HOSTS

显示 DNS 缓存中的主机名。

hostname
主机名。
ttl
距下次查询还剩多少秒。
addrs
逗号分隔的地址列表。

SHOW DNS_ZONES

显示缓存中的 DNS 区域。

zonename
区域名称。
serial
当前序列号。
count
属于此区域的主机名数量。

SHOW VERSION

显示 PgBouncer 版本字符串。

SHOW STATE

显示 PgBouncer 状态设置。当前状态为 active、paused 和 suspended。

进程控制命令

PAUSE [db]

PgBouncer 尝试断开与所有服务器的连接。断开每个服务端连接时,需根据服务端连接池的池化模式等待该连接被释放(事务池化模式下需等待事务完成,语句模式下需等待语句完成,会话池化模式下需等待客户端断开)。该命令在所有服务端连接断开之前不会返回。适用于数据库重启时使用。

若指定了数据库名称,则仅暂停该数据库。

连接到已暂停数据库的新客户端连接将等待,直到调用 RESUME

DISABLE db

拒绝指定数据库上的所有新客户端连接。

ENABLE db

在之前的 DISABLE 命令之后,允许新客户端连接。

RECONNECT [db]

关闭指定数据库或所有数据库中每个已打开的服务端连接,在其被释放后(根据池化模式),即使其生命周期尚未结束。新服务端连接可立即建立,并根据连接池大小设置按需连接。

此命令适用于服务端连接配置发生变化时,例如逐步切换到新服务器。当 pgbouncer.ini 中的连接字符串已更改并重新加载(见 RELOAD)或 DNS 解析发生变化时,无需执行此命令,因为等效操作会自动运行。仅当 PgBouncer 下游有某些组件负责路由连接时,才需要此命令。

运行此命令后,可能有一段时间部分服务端连接指向旧目标,部分指向新目标。这通常仅在将只读流量在只读副本之间切换,或在多主复制环境节点之间切换时才合理。若需要同时切换所有连接,建议使用 PAUSE。若需要不等待地立即关闭服务端连接(例如紧急故障转移而非渐进式切换),还可考虑 KILL

KILL [db]

立即断开指定数据库或所有数据库(不包括管理数据库)上的所有客户端和服务端连接。

连接到已被 kill 的数据库的新客户端连接将等待,直到调用 RESUME

KILL_CLIENT id

立即终止指定的客户端连接及该客户端的所有服务端连接。要终止的客户端由 SHOW CLIENTS 命令中找到的 id 值标识。

示例命令类似于 KILL_CLIENT 1234

SUSPEND

所有套接字缓冲区将被刷新,PgBouncer 停止监听其上的数据。该命令在所有缓冲区清空之前不会返回。适用于 PgBouncer 在线重启时使用。

连接到已挂起数据库的新客户端连接将等待,直到调用 RESUME

RESUME [db]

从之前的 KILLPAUSESUSPEND 命令中恢复工作。

SHUTDOWN

PgBouncer 进程将退出。

SHUTDOWN WAIT_FOR_SERVERS

停止接受新连接,并在所有服务端连接释放后关闭。这基本上等同于依次执行 PAUSESHUTDOWN,区别在于此命令在等待 PAUSE 期间也停止接受新连接,并主动断开正在等待服务端连接的客户端。请注意,关闭期间 UNIX 套接字将保持打开,但只接受到 PgBouncer 管理控制台的连接。

SHUTDOWN WAIT_FOR_CLIENTS

停止接受新连接,并在所有现有客户端断开后关闭进程。请注意,关闭期间 UNIX 套接字将保持打开,但只接受到 pgbouncer 管理控制台的连接。此命令可用于使用以下步骤对两个 PgBouncer 进程进行零停机时间的滚动重启:

  1. 让两个或更多 PgBouncer 进程使用 so_reuseport 在同一端口上运行(建议 配置对等,但非必须)。为了在重启时实现零停机时间,我们将逐个重启这些进程,让其他进程在某一进程重启期间继续接受连接。
  2. 选择一个进程先重启,称之为 A。
  3. 对进程 A 执行 SHUTDOWN WAIT_FOR_CLIENTS(或发送 SIGTERM)。
  4. 让所有客户端重新连接。可能需要等待一段时间,直到客户端侧连接池因其 server_idle_timeout(或类似配置)触发重连。如果没有客户端侧连接池,可能需要重启客户端。一旦所有客户端重新连接,进程 A 将自动退出,因为已没有客户端连接到它。
  5. 重新启动进程 A。
  6. 对其余每个进程逐个重复步骤 3、4 和 5,直到所有进程都重启完成。

RELOAD

PgBouncer 进程将重新加载其配置文件并更新可更改的设置。包括主配置文件以及由 auth_fileauth_hba_file 设置指定的文件。

PgBouncer 会检测配置文件重新加载是否更改了数据库定义的连接参数。到旧目标的现有服务端连接将在下次释放时关闭(根据池化模式),新服务端连接将立即使用更新后的连接参数。

WAIT_CLOSE [db]

等待指定数据库或所有数据库的所有服务端连接清除"close_needed"状态(见 SHOW SERVERS)。可在 RECONNECTRELOAD 之后调用,等待相应配置更改完全生效,例如在切换脚本中使用。

其他命令

SET key = arg

更改配置设置(另见 SHOW CONFIG)。例如:

SET log_connections = 1;
SET server_check_query = 'select 2';

(注意,此命令在 PgBouncer 管理控制台上运行,用于设置 PgBouncer 的配置项。在其他数据库上运行的 SET 命令将像普通 SQL 命令一样传递给 PostgreSQL 后端。)

信号

SIGHUP
重新加载配置。与在控制台执行 RELOAD 命令效果相同。
SIGTERM
超安全关闭。等待所有现有客户端断开连接,但不接受新连接。与在控制台执行 SHUTDOWN WAIT_FOR_CLIENTS 效果相同。若在已有关闭进程中再次收到此信号,则触发"立即关闭"而非"超安全关闭"。在 PgBouncer 1.23.0 之前的版本中,此信号会导致"立即关闭"。
SIGINT
安全关闭。与在控制台执行 SHUTDOWN WAIT_FOR_SERVERS 效果相同。若在已有关闭进程中再次收到此信号,则触发"立即关闭"而非"安全关闭"。
SIGQUIT
立即关闭。与在控制台执行 SHUTDOWN 效果相同。
SIGUSR1
与在控制台执行 PAUSE 效果相同。
SIGUSR2
与在控制台执行 RESUME 效果相同。

Libevent 设置

来自 Libevent 文档:

It is possible to disable support for epoll, kqueue, devpoll, poll or select by setting the environment variable EVENT_NOEPOLL, EVENT_NOKQUEUE, EVENT_NODEVPOLL, EVENT_NOPOLL or EVENT_NOSELECT, respectively.

By setting the environment variable EVENT_SHOW_METHOD, libevent displays the kernel notification method that it uses.


另请参阅

pgbouncer(5) - 配置设置描述手册页

https://www.pgbouncer.org/

4 - PgBouncer 编译与安装

PgBouncer 编译与安装说明

原始页面: https://www.pgbouncer.org/install.html


编译

PgBouncer 的编译依赖以下组件:

安装依赖后,执行以下命令:

$ ./configure --prefix=/usr/local
$ make
$ make install

如果从 Git 构建或在 Windows 上构建,请参阅下方的单独构建说明。


DNS 查询支持

PgBouncer 在每次连接时执行主机名查询,而非仅在配置加载时查询一次。这需要异步 DNS 实现。下表列出了支持的后端及其探测顺序:

后端并行EDNS0 (1)/etc/hostsSOA 查询 (2)备注
c-ares<=1.10 版本中 IPv6+CNAME 存在缺陷
evdns, libevent 2.x不检查 /etc/hosts 更新
getaddrinfo_a, glibc 2.9+是 (3)非 glibc 环境不可用
getaddrinfo, libc是 (3)需要 pthreads
  1. 若需要一个主机名对应 8 个以上 IP 地址,则需要 EDNS0 支持。
  2. SOA 查询用于在区域序列号变更时重新检查主机名。
  3. 要启用 EDNS0,请在 /etc/resolv.conf 中添加 options edns0

c-ares 是功能最完整的实现,推荐在大多数场景和二进制打包中使用(前提是有足够新的版本可用)。Libevent 内置的 evdns 在列出的限制条件下也适用于许多场景。其他后端目前基本属于遗留选项,不再接受太多测试。

默认情况下,若系统中存在 c-ares,则会优先使用它。可通过 configure --with-cares 强制使用,或通过 --without-cares 禁用。若不使用 c-ares(未找到或被禁用),则使用 Libevent。指定 --disable-evdns 可禁用 Libevent 的 evdns,并回退到基于 libc 的实现。


PAM 认证

要启用 PAM 认证,./configure 提供了 --with-pam 标志(默认值为 no)。编译时启用 PAM 支持后,将新增一个全局认证类型 pam,可通过 PAM 对用户进行鉴权。


LDAP 认证

要启用 LDAP 认证,./configure 提供了 --with-ldap 标志(默认值为 no)。编译时启用 LDAP 支持后,将新增一个全局认证类型 ldap,可通过 LDAP 对用户进行鉴权。


systemd 集成

要启用 systemd 集成,请使用 configure 选项 --with-systemd。这将允许使用 Type=notify(若使用 systemd 253 或更高版本,则可使用 Type=notify-reload)以及 socket 激活。示例请参见 etc/pgbouncer.serviceetc/pgbouncer.socket


从 Git 构建

从 Git 构建 PgBouncer 需要在运行 configure 之前先生成头文件和配置文件:

$ git clone https://github.com/pgbouncer/pgbouncer.git
$ cd pgbouncer
$ ./autogen.sh
$ ./configure
$ make
$ make install

默认情况下,所有文件将安装在 /usr/local 下。可向 configure 提供一个或多个命令行选项。运行 ./configure --help 可列出所有可用选项及用于自定义配置的环境变量。

额外需要的软件包:autoconf、automake、libtool、pandoc


测试

如需了解如何运行测试,请参阅 测试目录中的 README.md 文件


在 Windows 上构建

Windows 上唯一受支持的构建环境是 MinGW。不支持 Cygwin 和 Visual $ANYTHING。

在 MinGW 上构建,按照常规方式执行:

$ ./configure
$ make

如果从 Unix 交叉编译:

$ ./configure --host=i586-mingw32msvc

LDAP 构建选项目前不支持 Windows。


在 Windows 上运行

从命令行运行的方式与通常相同,但 -d(守护进程化)、-R(重启)和 -u(切换用户)选项无法使用。

要将 PgBouncer 作为 Windows 服务运行,需要配置 service_name 参数以设置服务名称。然后执行:

$ pgbouncer -regservice config.ini

要卸载服务:

$ pgbouncer -unregservice config.ini

要使用 Windows 事件日志,请在配置文件中设置 syslog = 1。但在此之前,需要先注册 pgbevent.dll

$ regsvr32 pgbevent.dll

要取消注册,执行:

$ regsvr32 /u pgbevent.dll

5 - 源码发布版下载

PgBouncer 源码发布版与二进制软件包

原始页面: https://www.pgbouncer.org/downloads/


PgBouncer 1.25

FileDateSizeSHA256
pgbouncer-1.25.1.tar.gz2025-12-03864801 bytessha256
pgbouncer-1.25.0.tar.gz2025-11-09863322 bytessha256

PgBouncer 1.24

FileDateSizeSHA256
pgbouncer-1.24.1.tar.gz2025-04-16717796 bytessha256
pgbouncer-1.24.0.tar.gz2025-01-10706573 bytessha256

PgBouncer 1.23

FileDateSizeSHA256
pgbouncer-1.23.1.tar.gz2024-08-02700025 bytessha256
pgbouncer-1.23.0.tar.gz2024-07-03694845 bytessha256

PgBouncer 1.22

FileDateSizeSHA256
pgbouncer-1.22.1.tar.gz2024-03-04677351 bytessha256
pgbouncer-1.22.0.tar.gz2024-01-31670589 bytessha256

PgBouncer 1.21

FileDateSizeSHA256
pgbouncer-1.21.0.tar.gz2023-10-16668211 bytessha256

PgBouncer 1.20

FileDateSizeSHA256
pgbouncer-1.20.1.tar.gz2023-08-09638844 bytessha256
pgbouncer-1.20.0.tar.gz2023-07-20638020 bytessha256

PgBouncer 1.19

FileDateSizeSHA256
pgbouncer-1.19.1.tar.gz2023-05-31623569 bytessha256
pgbouncer-1.19.0.tar.gz2023-05-04616947 bytessha256

PgBouncer 1.18

FileDateSizeSHA256
pgbouncer-1.18.0.tar.gz2022-12-12600825 bytessha256

PgBouncer 1.17

FileDateSizeSHA256
pgbouncer-1.17.0.tar.gz2022-03-23598294 bytessha256

PgBouncer 1.16

FileDateSizeSHA256
pgbouncer-1.16.1.tar.gz2021-11-11591450 bytessha256
pgbouncer-1.16.0.tar.gz2021-08-09592136 bytessha256

PgBouncer 1.15

FileDateSizeSHA256
pgbouncer-1.15.0.tar.gz2020-11-19588042 bytessha256

PgBouncer 1.14

FileDateSizeSHA256
pgbouncer-1.14.0.tar.gz2020-06-11578955 bytessha256

PgBouncer 1.13

FileDateSizeSHA256
pgbouncer-1.13.0.tar.gz2020-04-27574955 bytessha256

PgBouncer 1.12

FileDateSizeSHA256
pgbouncer-1.12.0.tar.gz2019-10-17567465 bytessha256

PgBouncer 1.11

FileDateSizeSHA256
pgbouncer-1.11.0.tar.gz2019-08-27571414 bytessha256

PgBouncer 1.10

FileDateSizeSHA256
pgbouncer-1.10.0.tar.gz2019-07-01480571 bytessha256

PgBouncer 1.9

FileDateSizeSHA256
pgbouncer-1.9.0.tar.gz2018-08-13469300 bytessha256

PgBouncer 1.8

FileDateSizeSHA256
pgbouncer-1.8.1.tar.gz2017-12-20465930 bytessha256
pgbouncer-1.8.tar.gz2017-12-19465612 bytessha256

PgBouncer 1.7

FileDateSizeSHA256
pgbouncer-1.7.2.tar.gz2016-02-26462374 bytessha256
pgbouncer-1.7.1.tar.gz2016-02-18461903 bytessha256
pgbouncer-1.7.tar.gz2015-12-18459080 bytessha256

PgBouncer 1.6

FileDateSizeSHA256
pgbouncer-1.6.1.tar.gz2015-09-03431076 bytessha256
pgbouncer-1.6.tar.gz2015-08-01412700 bytessha256

PgBouncer 1.5

FileDateSizeSHA256
pgbouncer-1.5.5.tar.gz2015-04-09336145 bytessha256
pgbouncer-1.5.4.tar.gz2012-11-28339610 bytessha256
pgbouncer-1.5.3.tar.gz2012-09-12339013 bytessha256
pgbouncer-1.5.2.tar.gz2012-05-29335338 bytessha256
pgbouncer-1.5.1.tar.gz2012-04-17334413 bytessha256
pgbouncer-1.5.tar.gz2012-01-05411488 bytessha256

PgBouncer 1.4

FileDateSizeSHA256
pgbouncer-1.4.2.tgz2011-06-16283204 bytessha256
pgbouncer-1.4.1.tgz2011-04-01282728 bytessha256
pgbouncer-1.4.tgz2011-01-11231691 bytessha256

PgBouncer 1.3

FileDateSizeSHA256
pgbouncer-1.3.4.tgz2010-09-09167957 bytessha256
pgbouncer-1.3.3.tgz2010-05-10167476 bytessha256
pgbouncer-1.3.2.tgz2010-03-15166756 bytessha256
pgbouncer-1.3.1.tgz2009-07-06161518 bytessha256
pgbouncer-1.3.tgz2009-02-18160154 bytessha256

PgBouncer 1.2

FileDateSizeSHA256
pgbouncer-1.2.3.tgz2008-08-08145372 bytessha256
pgbouncer-1.2.2.tgz2008-08-06145017 bytessha256
pgbouncer-1.2.1.tgz2008-08-04144903 bytessha256
pgbouncer-1.2.tgz2008-07-29143915 bytessha256

PgBouncer 1.1

FileDateSizeSHA256
pgbouncer-1.1.2.tgz2007-12-10122054 bytessha256
pgbouncer-1.1.1.tgz2007-10-26121042 bytessha256
pgbouncer-1.1.tgz2007-10-09120462 bytessha256

PgBouncer 1.0

FileDateSizeSHA256
pgbouncer-1.0.8.tgz2007-06-1893636 bytessha256
pgbouncer-1.0.7.tgz2007-04-1993086 bytessha256
pgbouncer-1.0.6.tgz2007-04-1292244 bytessha256
pgbouncer-1.0.5.tgz2007-04-1191934 bytessha256
pgbouncer-1.0.4.tgz2007-04-1191889 bytessha256
pgbouncer-1.0.3.tgz2007-04-1191489 bytessha256
pgbouncer-1.0.2.tgz2007-03-2890555 bytessha256
pgbouncer-1.0.1.tgz2007-03-1589609 bytessha256
pgbouncer-1.0.tgz2007-03-1388587 bytessha256

二进制软件包

许多操作系统发行版提供了 PgBouncer 的原生软件包/移植版本,建议首先检查您的系统中是否已有可用的版本。

以下专用构建可能提供比发行版仓库更新的版本:

6 - 版本变更日志

PgBouncer 版本历史与发布说明

来源: https://www.pgbouncer.org/changelog.html


PgBouncer 1.25.x

2025-12-03 - PgBouncer 1.25.1 - “Fixing a bunch of bugs before Christmas(圣诞节前修复一堆 Bug)”

  • 安全

    • 修复 CVE-2025-12819:在此版本之前,未经身份验证的攻击者可以在认证过程中,通过在 StartupMessage 中提供恶意的 search_path 参数来执行任意 SQL。同时满足以下所有条件的系统存在此漏洞:

      1. track_extra_parameters 包含 search_path(非默认配置,通常仅在涉及 Citus 或 PostgreSQL 18 的场景中配置)
      2. auth_user 被设置为非空字符串(非默认配置)
      3. auth_query 配置时未使用完全限定的对象名(默认配置,< 运算符未经 Schema 限定)
  • 修复

    • 修复重连服务器后临时 SCRAM 认证的错误( #1432,引入自 1.25.0)
    • 为不支持 SIMD 的特殊架构补充缺失的类型定义( #1414,引入自 1.25.0)
    • 移除客户端在发送任何数据之前关闭连接时产生的噪音警告日志( #1420,引入自 1.25.0)
    • 防止潜在的 NULL 指针解引用( #1423,引入自 1.25.0)
    • 修复潜在的内存泄漏( #1422,引入自 1.25.0)
    • 修复 SCRAM 对服务端消息的解析( #1431,引入自 1.25.0)

2025-11-09 - PgBouncer 1.25.0 - “The one with LDAP support(支持 LDAP 的版本)”

  • 功能
    • 新增 LDAP 认证支持!可通过 HBA 文件或使用 auth_ldap_options 进行配置。( #731
    • 新增客户端侧直连 TLS 支持。这使客户端能够使用 PostgreSQL 17 引入的更快速的 TLS 连接建立方式。PgBouncer 暂不支持通过此更快方式连接 PostgreSQL 服务器。( #1359
    • SHOW CLIENTS 中新增空闲状态字段。( #1191
    • 新增 transaction_timeout 设置,支持全局配置及用户级别配置。( #1242
    • 若客户端排队等待超过 5 秒仍未获得连接,则向客户端发送 NOTICE 消息。此时长可通过 query_wait_notify 修改或禁用。( #1264
    • 新增 scram_iterations 设置,允许运维人员在安全性与认证速度之间做出权衡。( #1339
    • 新增 client_tls13_ciphersserver_tls13_ciphers,用于选择启用哪些 TLSv1.3 加密套件。( #1352
  • 变更
    • 大幅提升临时 SCRAM 认证的性能。( #1338
    • 允许 KILL 命令不指定数据库,此时表示终止所有数据库。( #1317
    • 健康检查查询默认改为发送空查询,而非 SELECT 1。( #1233
    • 将完整的 PAM 队列记录为警告日志,便于排查由此引起的慢查询原因。( #1297
    • RELOAD 命令现在会报告重载过程中发生的任何错误。( #1231
    • 在关闭过程中开放对 PgBouncer UNIX 套接字的管理连接访问。这使运维人员更容易排查 PgBouncer 进程无法关闭的原因,并可手动执行 KILL_CLIENT 终止卡住的连接。( #1305
    • 修改 mkauth.py,不再添加已废弃的第三个字段。( #1365
    • 改进 disconnect_clientdisconnect_server 函数中的 FATAL 消息。( #1382
    • 停止使用已废弃的 OpenSSL 函数 EVP_PKEY_get0_EC_KEY,该函数可能在某些 FIPS 实现中引发问题。( #1384
  • 修复
    • 修复涉及长密码(1024 个字符或以上)的崩溃问题。( #1215
    • 修复使用 server_tls_sslmode=verify-full 时多主机连接的问题。( #1303
    • 修复转发取消请求时偶发的 FATAL 错误。( #1383
    • 修复 SHOW CONFIG 中参数的排序问题。( #1403
    • 加固启动包的解析逻辑。( #1407

PgBouncer 1.24.x

2025-04-16 - PgBouncer 1.24.1 - “CVE-2025-2291 VALID UNTIL yesterday(CVE-2025-2291 昨天已到期)”

  • 安全

    • 修复 CVE-2025-2291:此前 PgBouncer 在通过 auth_query 查询密码哈希时,未考虑用户密码的 VALID UNTIL 有效期。因此,若将 PgBouncer 用作 PostgreSQL 前端的透明代理,可能允许已过期的密码通过验证。为解决此问题,文档中默认 auth_query 及自定义 auth_query 函数的示例均已更新,以正确处理 VALID UNTIL。如果您使用的是自定义 auth_query,请相应更新。如果您使用的是默认 auth_query,可以升级到 PgBouncer 1.24.1,或在旧版本中手动修改配置以使用新的默认 auth_query
  • 修复

    • 通过回退 HBA 文件中 pam 认证支持来修复 PAM 问题。( #1291)(Bug 引入自 1.24.0)
    • 修复用户连接计数递减时的 Bug。该修复已包含在 GitHub 上的 1.24.0 标签中,但发布压缩包未包含此修复。( #1238)(Bug 引入自 1.24.0)
    • test_load_balance_hosts.py 添加到发布压缩包中。( #1282
    • 修复测试相关问题,以便 Debian 打包人员可以正常运行测试。( #1266#1250
  • 文档

    • 更新 auth_query 示例,设置安全的 search_path。( #1245

2025-01-10 - PgBouncer 1.24.0 - “New year, new bouncer(新年,新连接池)”

  • 功能

    • 新增对 systemd Type=notify-reload 的支持,需要 systemd 253 或更高版本。( #1148
    • 在管理控制台新增 KILL_CLIENT 命令,允许强制终止客户端连接。( #1147
    • 新增 max_user_client_connections 设置,支持全局配置及用户级别配置。( #1137
    • 新增 max_db_client_connections 设置,支持全局配置及数据库级别配置。( #1138
    • SHOW USERSSHOW DATABASES 输出中新增 current_client_connections 计数器。( #1137#1138
    • 新增 load_balance_hosts 参数,支持禁止在多个主机之间进行负载均衡。( #736
    • SHOW STATS 中暴露预备语句使用计数器。( #1192
    • 新增 client_idle_timeout 设置。( #1189
    • 新增用户级别的 query_timeoutreserve_pool_size。( #1180#1228
    • 在 HBA 文件中启用 pam 认证支持。( #326
  • 变更

    • TLS 配置未发生变更时,RELOAD 不再回收连接。此前只要执行 RELOAD,所有 TLS 连接都会被回收,可能导致短暂但严重的性能下降。现在仅在 TLS 设置实际发生变更时才会触发回收。( #1157
    • 默认启用预备语句支持,max_prepared_statements 默认值现为 200。此默认值变更仅影响实际使用预备语句的客户端。如果您使用预备语句,建议阅读 文档 中关于预备语句支持限制的说明。( #1144
    • 套接字、客户端和服务器现在可通过唯一 ID 在管理输出中进行标识。此前使用指针标识,但指针在断开连接后常被新客户端复用。( #1172
    • 对空 pidfile 提供更清晰的错误提示。( #1195
    • server_login_retry 失败时,将原始错误返回给客户端。( #1152
    • auth_query 出错时,在日志中记录原始服务器错误。( #1187
    • default_pool_size 设置为 0 表示不限制大小。( #1227
    • 将数据库级别的 reserve_pool 设置重命名为 reserve_pool_size,原名称仍作为别名保留。( #1232
  • 修复

    • 更好地处理各种低概率错误情况,例如 OOM 错误,此类情况此前可能导致崩溃或内存泄漏。( #1108#1101#1099#1169#1202
    • 修正示例配置文件中 server_tls_sslmode 的默认值。( #1133
    • 移除文档中对 server_tls_protocols 无效别名的描述。( #1155
    • 修复同时使用 auth_query 和复制连接时的 Bug,该 Bug 会导致此类场景下的连接失败。( #1166
    • PgBouncer 配置服务器参数期间忽略客户端取消请求。( #298

PgBouncer 1.23.x

2024-08-02 - PgBouncer 1.23.1 - “Everything is put back in order(一切恢复有序)”

  • 修复
    • 修复 PgBouncer 重载配置后可能发生的段错误。( #1105)(Bug 引入自 1.23.0)
    • 修复所有已知的 put_in_order 崩溃问题。( #1120)(新崩溃引入自 1.23.0)
    • 将发布压缩包中缺失的测试所需文件补充完整。( #1124)(文件缺失引入自 1.23.0)

2024-07-03 - PgBouncer 1.23.0 - “Into the new beginnings(迈向新的起点)”

  • 功能

    • 新增滚动重启支持。SIGTERM 不再触发 PgBouncer 进程的立即关闭,现在改为执行"超安全关闭":等待所有客户端断开连接后再关闭。新的 SIGTERM 行为允许在负载均衡器后对多个 PgBouncer 进程进行滚动重启,或在使用 so_reuseport 监听同一端口的场景下滚动重启。这是一个次要的破坏性变更:如果您在 Dockerfile 或 Systemd 服务文件中依赖 SIGTERM 的旧行为,现在应改用 SIGQUIT。( #902
    • 新增对 certpeer 认证方式的用户名映射支持。此功能提供了灵活性,使发起连接的用户无需与数据库用户相同。PgBouncer 对用户名映射的支持与 PostgreSQL 非常相似,但存在文档中列出的若干例外。( #996
    • 新增通过 PgBouncer 进行复制连接的支持。( #876
  • 变更

    • 改进 SHOW USERS 输出中的连接列表展示。( #1040
    • 允许按用户配置 pool_size。( #1049
    • 允许按数据库配置 server_lifetime。( #1057
    • SHOW USERS 输出中支持列举动态创建的用户。( #1052
    • 在 HBA 配置中支持 all 地址类型。( #1078
    • 支持使用 systemd 时自动重启。( #1080
    • 将 c-ares 最低版本要求提升至 1.9.0。( #1076
  • 修复

    • 修复处理大型及不完整启动包时的问题。( #1058
    • 在 options 启动参数中新增对 --config=value 格式的支持。( #1064
    • 修复 avg_wait_time 指标计算错误。( #727
    • 新增与客户端协商 PostgreSQL 协议版本的支持。( #1007
    • auth_query 添加未完成请求的处理。( #1034
    • 多项文档与 CI 改进。

PgBouncer 1.22.x

2024-03-04 - PgBouncer 1.22.1 - “It’s summer in Bangalore(班加罗尔的夏天)”

  • 修复
    • 修复部分客户端使用 COPY FROM STDIN 查询时引发的问题。此类查询可能导致内存泄漏、性能回退以及预备语句行为异常。 (#1025) (漏洞引入自 1.21.0)
    • 在发布压缩包中补充缺失的测试用例 (#1026) (测试文件缺失问题引入自 1.19.0 和 1.21.0)

2024-01-31 - PgBouncer 1.22.0 - “DEALLOCATE ALL(取消分配所有语句)”

  • 功能

    • max_prepared_statements 设置为非零值时,新增对 DEALLOCATE ALLDISCARD ALL 的支持(普通的 DEALLOCATE 仍不受支持)。 (#972)
    • 支持按数据库单独配置 auth_query。 (#979)
  • 变更

    • 改进推荐的 systemd 单元文件中的设置。 (#983)
    • 使快速失败逻辑能够处理所有无法再向数据库建立有效连接的场景。 (#998)
    • 多处文档改进。
  • 修复

    • 修复在 PG14 及更高版本中,PgBouncer 每次事务都会发送 SET DateStyle='ISO' 的问题。 (#879)
    • 修复对空 application_name 的处理问题。 (#999)
    • 修复在 Windows 上使用 OpenSSL 3.2.0 时的编译问题。 (#1009)

PgBouncer 1.21.x

2023-10-16 - PgBouncer 1.21.0 - “The one with prepared statements(预备语句版本)”

  • 功能

    • 新增对协议层命名预备语句的支持!这可能是 PgBouncer 呼声最高的功能之一。将预备语句与 PgBouncer 配合使用,可以大幅降低系统的 CPU 负载(PgBouncer 侧和 PostgreSQL 侧均如此)。在合成基准测试中,该功能能够将查询吞吐量提升 15% 至 250%,具体幅度取决于工作负载。要使用此新功能,需要将新参数 max_prepared_statements 设置为非零值(具体数值取决于您的工作负载,100 通常是一个合理的起点)。有关该功能的工作原理、限制及调优方法,请参阅 max_prepared_statements 文档。完成配置后,还需确保您的客户端库实际使用了预备语句,具体方式因客户端而异,请参阅所使用客户端的文档。该功能在发布前经过了充分测试,但由于其复杂性,仍可能存在性能问题或缺陷,如有发现请及时反馈。 (#845)
  • 变更

    • 改进 OpenSSL 安全设置,之前使用的默认值已严重过时。此版本起默认值与运行 PgBouncer 的系统 OpenSSL 默认值保持一致。 (#948libusual/#41)
    • PgBouncer 现在在可能的情况下使用 OpenSSL 计算 MD5 哈希,这是以符合 FIPS 标准的方式使用 PgBouncer 的必要条件。 (#949)
    • 即使没有客户端连接到 PgBouncer,也为拥有强制用户的连接池维持 min_pool_size。 (#947)
    • PgBouncer 在取消令牌中编码 peer_id 的方式已更改,这意味着不同版本的 PgBouncer 之间若未同时处于 v1.21.0 版本边界的同一侧,则无法正常互联。 (#945)
  • 修复

    • 修复带有错误信息 “FATAL in function client_proto(): bad client state: 6/7” 的崩溃问题。 (#928)(漏洞引入自 1.18.0)
    • 修复带有错误信息 “FATAL in function server_proto(): server in bad state: 11” 的崩溃问题。 (#927)(漏洞引入自 1.18.0)
    • 降低取消请求的日志记录级别。 (#903)
    • 修复对等节点的 slog 日志前缀问题。 (#922)
    • 修复文档中的拼写错误。 (#932)
    • 修复静态分析器指出的错误。 (#943)
    • 不再因登录阶段的临时 FATAL 错误而终止所有等待中的客户端连接。 (#946)
    • auth_dbname 中的数据库未显式配置时,使用自动数据库。 (#921)
  • 清理

    • 移除对 udns 的支持。 (#938)

PgBouncer 1.20.x

2023-08-09 - PgBouncer 1.20.1 - “Optional options(可选的选项)”

  • 修复
    • 修复将 options 加入 ignore_startup_parameters 后,不再忽略 options 启动参数中未知参数的回退问题。 (#908)(回退引入自 1.20.0)
    • 修复文档中令人困惑的拼写错误。 (#917)

2023-07-20 - PgBouncer 1.20.0 - “A funny name goes here(此处应有一个有趣的名字)”

  • 废弃声明

    • 在线重启选项现已被视为废弃。该功能近年来几乎未得到维护,存在多个已知问题,且新增功能通常不支持它。目前推荐的在线重启方式是使用 so_reuseportpeers 功能,这样可以让多个 PgBouncer 进程监听同一端口,通过逐一重启各进程,始终保证有一个 PgBouncer 进程在目标端口上监听。 (#894)
  • 功能

    • 引入 track_extra_parameters 参数,允许在事务池化模式下追踪更多参数。此前 PgBouncer 仅追踪 application_nameDateStyleTimeZonestandard_conforming_strings。此版本起,PgBouncer 默认还追踪 IntervalStyle。通过修改 track_extra_parameters,可以追踪更多设置,但仅限于 PostgreSQL 会向客户端回报的参数。如果使用 Citus 12.0 及以上版本,Citus 会确保 PostgreSQL 也将 search_path 回报给客户端,因此可以将 search_path 添加到 track_extra_parameters 设置中。 (#867)
    • 在认证阶段转发 SQLSTATE,这允许检测数据库不存在的情况,该功能由 Npgsql(.NET 的 PostgreSQL 数据提供程序)使用。 (#814)
    • server_tls_sslmode 的默认值更改为 prefer。 (#866)
    • 新增对 options 启动参数的支持,允许使用 psql 和 libpq 所支持的 PGOPTIONS 环境变量,通过该变量可以在启动时设置任意 PostgreSQL 参数。此功能仅适用于 PgBouncer 通过 track_extra_parameters 追踪的 PostgreSQL 参数。 (#878)
  • 修复

    • 修复将 pgbouncer 管理数据库用作 auth_dbname 时的崩溃问题。该用法仍不受支持,但现在会给出明确的错误提示而非直接崩溃。 (#817)
    • 修复 SHOW MEMpeer_cache 的名称显示错误(之前错误地显示为 db_cache)。 (#864)
    • 修复日志中源地址与目标地址混淆的问题(PgBouncer 原本应记录目标 IP,却记录了源 IP)。 (#880)
    • 仅在 log_connections 设置为 1 时,才记录通过 UNIX 套接字进行的管理连接日志。 (#883)

PgBouncer 1.19.x

2023-05-31 - PgBouncer 1.19.1 - “Sunny Spring(晴朗的春天)”

本次为小版本发布,修复了若干近期引入的缺陷:

  • 修复
    • 修复:FATAL in function disconnect_client(): bad client state: 0 (#846) (漏洞引入自 1.18.0)
    • 修复:FATAL in function server_proto(): server in bad state: 14 (#849) (漏洞引入自 1.18.0)
    • 在发布压缩包中补充运行 Python 测试所需的文件。 (#852) (新测试引入自 1.19.0)

2023-05-04 - PgBouncer 1.19.0 - “The old-fashioned, human-generated kind(老派的、人工生成的那种)”

  • 功能

    • 新增 auth_dbname 选项,用于指定运行 auth_query 所使用的数据库。 (#764)
    • 新增 SHOW STATE 命令,显示 PgBouncer 当前处于活跃、暂停还是挂起状态。 (#528)
    • 新增对 PgBouncer 进程间互联(peering)的支持。此功能允许在多个不同的 PgBouncer 进程位于同一负载均衡器后端时,查询取消请求仍能正常工作。 (#666)
    • 新增专用的 cancel_wait_timeout 设置,用于指定转发取消请求的超时时长,默认为 10 秒。 (#833)
    • 新增测试框架。 (#792)
  • 修复

    • 修复 TLS 握手失败时可能发生的内存泄漏问题。 (#796)
    • 在 Windows 上,为不支持的命令行选项提供更准确的错误提示信息。 (#620)
    • 修复在服务器处于 BEING_CANCELED 状态时调用 disconnect_server 的问题。 (#815)(引入自 1.18.0)
    • 修复接收到 SIGTERM 信号时以非零状态码退出的问题。 (#834)
    • unix_socket_dir 中无法创建套接字时,于启动阶段立即报错退出。 (#830)
    • listen_addr 中所有地址均无法监听时,于启动阶段立即报错退出。 (#838)
    • sbuf_connect 失败时,输出包含更多信息的警告日志,这在 UNIX 套接字创建失败时尤为有用。 (#837)
  • 清理

    • 多项 CI 更新以提升性能
    • 移除 AppVeyor

PgBouncer 1.18.x

2022-12-12 - PgBouncer 1.18.0 - “No real mystery(并无真正的谜团)”

  • 功能

    • SHOW CLIENTS/SERVERS/SOCKETS 输出中新增 application_name 字段。 (#449)
    • SHOW CLIENTS/SERVERS/POOLS 输出中新增取消请求相关信息。 (#782)
  • 修复

    • 当目标套接字已关闭时,sbuf_send_pending 操作立即失败。 (#652)
    • 修复若干可能导致崩溃的问题。 (#700#730)
    • 修复逗号分隔主机列表功能中的整数溢出缺陷,该缺陷会导致连接被错误路由到 UNIX 套接字。 (#747)
    • 不再为维持 min_pool_size 而驱逐现有连接。 (#648)
    • 修复与 PostgreSQL 15 一起使用时 SHOW HELP 的问题。 (#769)
    • 修复查询取消处理中的竞争条件。此前,针对某个客户端的查询取消请求有可能取消另一个客户端的查询——当 PgBouncer 收到取消请求时,被取消的查询已自行完成,就会发生这种情况。 (#717)
  • 清理

    • 多项 CI 更新

PgBouncer 1.17.x

2022-03-23 - PgBouncer 1.17.0 - “A line has been drawn”(界限已划定)

  • 功能

    • 数据库定义现在可以指定以逗号分隔的主机列表,连接时将以轮询方式依次访问各主机。
    • 连接到不存在的数据库时,错误信息(“no such database”)现在会在身份验证完成后才返回。这可以防止未经验证的客户端探测数据库是否存在。(与 1.15.0 版本中将用户不存在的错误推迟到验证后报告的变更类似。)
    • 登录前不再向客户端发送服务器断开连接的错误信息。此前这可能会将配置细节等非公开信息泄露给尚未登录的客户端。
    • 再次提高最大密码长度上限。显然上一次的调整仍不足够。
    • 移除 auth_file 的自动重载功能。auth_file 现在仅在配置文件重载时才会重新读取,不再在文件变更后自动加载。
    • Windows 构建版本现已包含版本信息资源文件。
    • CI 生成的 Windows 构建版本现采用静态链接,可直接使用,无需额外依赖。
  • 修复

    • 修复了 OpenSSL 3 的支持问题。之前的版本会导致崩溃。
    • 连接时不再应用快速失败(fast-fail)机制。这是上述"在验证前不报告服务器错误"变更的一部分。同时也修复了 SCRAM 透传认证场景中的特殊问题——在该场景下,需要允许客户端侧的认证交换,以便通过重新认证来修复服务端连接。快速失败机制仍会在认证完成后立即生效,因此在大多数情况下,实际可观察到的行为保持不变。
    • 将示例 pgbouncer.ini 中的 auth_type 改为 md5,以与内置默认值保持一致。由于部分用户直接将此文件作为默认配置文件使用,请检查这一配置变更是否适合您的环境。
    • 修复在启用断言的构建版本中退出时发生的崩溃问题。
    • 改进 tcp_defer_accept 的文档说明和行为。文档中关于默认值的描述此前存在错误和误导性,在某些情况下 “show config” 显示的值也不正确。此外,若该选项已设置但不受支持,现在将报错而非忽略,与其他平台相关 socket 选项的处理方式保持一致。
    • 修复 Windows 上使用 c-ares 的构建问题。Windows 上现在要求 c-ares >= 1.18.0。
  • 清理

    • 清理了 Autoconf >= 2.70 产生的大部分弃用警告,仍支持旧版本的 Autoconf。
    • Cirrus CI 的使用已扩展到更多平台。
    • 已移除对 Travis CI 的支持。
    • 更新了默认根 CA 文件的搜索路径,以覆盖更多平台,例如 Fedora/RHEL/CentOS。
    • 所有 Python 脚本现在默认使用 python3,不再维护 Python 2 兼容性。
    • 测试套件脚本改用 command -v 替代已弃用的 which
    • 多条错误信息已重新措辞,以更清晰地说明其对应的命令或配置项。
    • 测试套件脚本不再依赖 GNU sed。
    • make check 现在可在 Windows 上运行(但 SSL 测试套件暂不支持)。
    • 文档中说明了管理控制台仅支持简单查询协议,并针对此问题提供了更清晰的错误提示。

PgBouncer 1.16.x

2021-11-11 - PgBouncer 1.16.1 - “Test of depth against quiet efficiency”(以深度检验静默效率)

这是一个包含安全修复的小版本发布。

  • 使 PgBouncer 作为服务器时,拒绝在 SSL 或 GSS 加密握手后接收多余数据。

    具有 TCP 连接数据注入能力的中间人攻击者,可能在本应受加密保护的数据库会话开始时塞入明文数据。这可能被用于向服务器发送伪造的 SQL 命令,但仅在 PgBouncer 不要求任何身份验证数据时才有效。(不过,依赖 SSL 证书认证的 PgBouncer 部署恰恰可能不要求验证。)(CVE-2021-3935)

2021-08-09 - PgBouncer 1.16.0 - “Fended off a jaguar”(击退了一头美洲虎)

  • 功能

    • 支持 TLS 设置的热重载。重载配置文件时,变更的 TLS 设置会自动生效。
    • 新增对抽象 UNIX 域套接字的支持。在 UNIX 域套接字路径前加 @ 前缀即可使用抽象命名空间中的套接字。这与 PostgreSQL 14 中的对应功能保持一致。
    • 密码和用户名的最大长度分别提升至 996 和 128 个字符。多种云服务有此需求。
    • 最小连接池大小现在可以按数据库单独配置,与常规连接池大小和保留连接池大小的配置方式相同。
    • SHOW POOLS 中新增显示待处理查询取消请求的数量。
  • 修复

    • 配置解析在多处增强了错误处理的严格程度。此前可能仅记录错误并继续运行的情况,现在将导致启动失败。这才是应有的正确行为,但部分代码之前并未做到。某些用户可能会发现其配置一直存在问题,并将无法继续使用。
    • 修复了查询取消的处理逻辑。在某些情况下,取消请求会莫名地卡住很长时间,此问题现已解决。事实上,取消请求现在可以超出连接池大小两倍,因此不应再出现卡住的情况。( #542#543
    • 修复了通过 HBA 混用 md5 和 scram 认证的问题。
    • 修复了 Windows 上使用 c-ares 的构建问题。
    • 修复了令人头疼的"FIXME: query end, but query_start == 0"日志信息。我们现在已知其成因,您不应再看到这条信息。( #565
    • 修复 default_pool_sizemin_pool_sizeres_pool_size 的热重载问题。此前重载这些配置项不会生效。
  • 清理

    • 现已改用 Cirrus CI,不再使用 Travis CI。
    • 照例新增了许多测试用例。
    • “unclean server"日志信息已进一步明确。现在会显示"client disconnect while server was not ready"或"client disconnect before everything was sent to the server”。前者可能发生在客户端断开时服务器仍有事务块未关闭的情况下,此前曾令部分用户感到困惑。
    • 不再允许将"pgbouncer"用作数据库名称。该名称为管理控制台保留,将其用作普通数据库名称从未真正正常工作过,现已明确禁止。
    • 在关闭连接前发送给客户端的错误信息现在标记为 FATAL 而非 ERROR。部分客户端此前会因此产生困惑。( #564
    • 修复了 GCC 11 的编译警告。( #623

PgBouncer 1.15.x

2020-11-19 - PgBouncer 1.15.0 - “Ich hab noch einen Koffer in Berlin”(我在柏林还有一只行李箱)

  • 功能

    • 改进认证失败的错误报告。发送给客户端的认证失败消息现在只说明认证失败,不再提供进一步细节,详细信息可在 PgBouncer 日志中查看。此外,若请求的用户不存在,认证流程仍会完整执行,并返回相同的通用失败消息。这些改动可防止客户端探测 PgBouncer 实例中存在的用户名及其他认证相关信息,与 PostgreSQL 的行为保持一致。
    • 客户端立即断开连接时不再记录日志。这可以避免监控系统仅建立 TCP/IP 连接但未发送任何数据就断开时产生大量日志噪音。
    • 使用 systemd journal 时改用其进行日志输出。当检测到标准错误输出指向 systemd journal 时,使用 systemd 原生函数输出日志,避免重复打印时间戳和进程 ID,使日志更加整洁。同时,这也为日志添加了严重级别等元数据,使 journal 转发至 syslog 时消息能携带有用的元数据。
    • 测试套件的部分内容现在可以在 Windows 上运行。
    • SHOW CONFIG 现在同时显示各配置项的默认值。
  • 修复

    • 修复 FreeBSD 上的 so_reuseport 选项。PgBouncer 1.12.0 中的原始实现在 FreeBSD 上实际无法工作。( #504
    • 修复在旧版 systemd 系统上的编译问题。该问题在 1.14.0 中引入。( #505
    • 修复了用于构建 Windows 二进制 zip 包的 Makefile 目标。
    • 长格式命令行选项现在也可以在 Windows 上正常使用。
    • 修复全局 auth_user 配置项的行为。旧的行为取决于配置文件中的顺序,容易造成混乱且不稳定,现已不再如此。( #391#393
  • 清理

    • 提高测试的稳定性和可移植性。
    • 现代化 Autoconf 相关代码。
    • 禁用来自 OpenSSL 3.0.0 的弃用编译警告。

PgBouncer 1.14.x

2020-06-11 - PgBouncer 1.14.0 - “La ritrovata magia”(重拾的魔法)

  • 功能

    • 新增 SCRAM 认证透传支持。允许在 PgBouncer 中使用加密的 SCRAM 密钥(来自 userlist.txtauth_query)登录后端服务器。
    • 新增对 systemd socket 激活的支持。在对 /var/run/postgresql 访问受限的系统上,这对于让 systemd 管理 UNIX 域套接字的创建尤为有用。
    • 新增 Windows 上对 UNIX 域套接字的支持。
  • 清理

    • 新增一个更精简的备用示例配置文件 pgbouncer-minimal.ini,供测试或部署使用。

PgBouncer 1.13.x

2020-04-27 - PgBouncer 1.13.0 - “My favourite game”(我最喜欢的游戏)

  • 功能

    • 新增配置项 tcp_user_timeout,用于设置对应的 socket 选项。
    • client_tls_protocolsserver_tls_protocols 现在默认值为 secure,即仅启用 TLS 1.2 和 TLS 1.3。旧版本仍受支持,只是默认不启用。
    • 新增对 systemd 服务通知的支持。目前支持使用 Type=notify 服务单元,未来版本计划提供更深入的集成。
  • 修复

    • 修复多行日志消息问题( libusual #24
    • 正确处理 auth_query 返回的空用户名( #340
  • 清理

    • 移除了 debian 目录下的 Debian 打包文件,建议使用来自 https://apt.postgresql.org/ 的软件包。
    • 对测试套件进行了大量修复和改进。
    • 测试默认不再尝试使用 sudo,现在可以通过设置环境变量 USE_SUDO 来显式启用。
    • libevent API 的使用已更新为版本 2 风格的接口,不再使用版本 1 中已弃用的接口。

PgBouncer 1.12.x

2019-10-17 - PgBouncer 1.12.0 - “It’s about learning and getting better”(关于学习与持续进步)

本版本包含多项小幅功能增强与缺陷修复。

  • 功能

    • 新增启用 SO_REUSEPORT 套接字选项的配置项。在部分操作系统上,该选项允许在同一主机上运行多个 PgBouncer 实例,监听相同端口,并由内核自动分发连接。
    • 新增使用独立于操作系统的 resolv.conf 文件的配置项。这允许设置自定义 DNS 服务器以及其他 DNS 选项。
    • SHOW VERSION 的输出从 NOTICE 消息改为普通结果行返回。这样更易于处理,并与其他 SHOW 命令保持一致。
  • 修复

    • 将统计列的类型从 bigint 改为 numeric 发送。这避免了在值超出 bigint 范围时某些客户端库报错的问题。( #360#401
    • 修复 PAM 用户密码丢失的问题。( #285
    • 接受启用了 SCRAM channel binding 的客户端。此前,支持 channel binding 的客户端(即 PostgreSQL 11+)在某些情况下连接 PgBouncer 时会失败。(PgBouncer 本身不支持 channel binding,此修复仅为兼容提供该功能的客户端。)
    • 修复与较新版本 musl-libc(Alpine Linux 所用)的编译兼容性问题。
  • 清理

    • 新增 make check 目标,允许通过单个命令运行所有测试。
    • 移除对 PostgreSQL wiki 的引用,相关信息现已全部收录于 PgBouncer 文档或官网中。
    • 移除对 Libevent 1.x 版本的支持,现在要求使用 Libevent 2.x。Libevent 现通过 pkg-config 进行检测。
    • 修复 macOS 和 Windows 上的编译器警告,这两个平台的构建现在应无警告。
    • 修复 LLVM scan-build 报告的若干警告。

PgBouncer 1.11.x

2019-08-27 - PgBouncer 1.11.0 - “Instinct for Greatness”(卓越的本能)

  • 功能
    • 新增对客户端和服务端 SCRAM 认证的支持,添加了新的认证类型 scram-sha-256
    • 当存储密码为 md5 格式时,auth_type=password 的处理行为与 PostgreSQL 服务器保持一致。( #129
    • 新增 log_stats 选项,用于禁止将统计信息打印到日志。( #287
    • 在日志时间戳中添加时区信息。
    • 在日志前缀中以方括号包裹 PID。
  • 修复
    • 修复在针对较新版本 OpenSSL(使用 -Werror)运行时的 OpenSSL 配置检测问题。
    • 修复使用 auth_user 时等待时间的计算错误,该问题会导致程序崩溃或报告错误的等待时间。( #393
    • 处理 PostgreSQL 12 新增的 GSSENCRequest 数据包。当前该处理不执行任何操作,但可避免出现关于"bad packet header"的令人困惑的错误信息。
  • 清理
    • 对测试套件进行了大量改进,并新增了若干测试用例。
    • 修复 Windows 上的多个编译器警告。
    • 扩展了 [users] 节的文档说明,并在示例配置文件中补充了相关内容。( #330

PgBouncer 1.10.x

2019-07-01 - PgBouncer 1.10.0 - “Afraid of the World”(对世界的畏惧)

  • 功能
    • 新增启用和禁用 TLS 1.3 的支持。(TLS 1.3 在之前已可依赖 OpenSSL 库的版本获得支持,但现在配置 TLS 协议版本的相关设置项也正式支持 TLS 1.3。)
  • 修复
    • 修复 TLS 1.3 支持问题,该问题在 OpenSSL 1.1.1 和 1.1.1a 版本中存在(更早或更新版本不受影响)。
    • 修复 SHOW FDS 命令中偶发的崩溃问题。( #311
    • 修复大量取消请求到达时可能导致长时间宕机的问题。( #329
    • 避免 PostgreSQL 执行 reload 后出现"unexpected response from login query"错误。( #220
    • 修复 idle_transaction_timeout 的计算错误,该缺陷会在特定情况下导致过早超时。( #125
  • 清理
    • 使各类日志和错误信息更加精确。
    • 修复 Coverity 发现的若干问题(均对实际运行无显著影响)。
    • 改进所有测试脚本并补充文档说明。
    • 在文档中新增若干 SHOW 命令的说明。
    • 将文档格式从 rst 转换为 Markdown。
    • 源码树中的 Python 脚本现已全部兼容 Python 3。

PgBouncer 1.9.x

2018-08-13 - PgBouncer 1.9.0 - “Chaos Survival”(混乱中求生)

  • 功能
    • 新增 RECONNECT 命令。
    • 新增 WAIT_CLOSE 命令。
    • 快速关闭——在会话池模式下,若服务器连接处于"close_needed"(重连)状态,立即断开该连接。
    • 在 SHOW SERVERS 输出中新增 close_needed 列。
  • 修复
    • 避免 parse_filename 中的双重释放(double-free)问题。
    • 避免 parse_line 中的空指针解引用问题。
  • 清理
    • mkauth.py 移植到 Python 3。
    • 改进信号(signals)相关文档。
    • 改进快速入门文档。
    • 补充 SET 命令的文档说明。
    • 更正所需软件列表。
    • 修复 -Wimplicit-fallthrough 编译警告。
    • 补充多个 SHOW 字段的缺失文档说明。
    • 补充 reload 和 DNS 变更时的重连行为说明。
    • 说明 KILL 命令之后需执行 RESUME。
    • 补充 server_lifetime 文档说明。
    • 修正消息和文档中的错别字及大小写问题。
    • 修复测试中 psql 的调用方式。
    • 其他若干测试环境改进。

PgBouncer 1.8.x

2017-12-20 - PgBouncer 1.8.1 - “Ground-and-pound Mentality”(摔打磨练的心态)

  • 修复
    • 将头文件 include/pam.h 加入发布压缩包。该文件缺失导致 1.8 版本的压缩包完全无法构建。

2017-12-19 - PgBouncer 1.8 - “Confident at the Helm”(掌舵自如的自信)

  • 功能
    • 支持 PAM 认证(通过 --with-pam 启用)。
    • SHOW DATABASES 输出中新增 pauseddisabled 字段。
    • SHOW POOLS 输出中新增 maxwait_us 字段。
    • SHOW 命令输出中新增 waitwait_us 字段。
    • 新增 SHOW STATS_TOTALSSHOW STATS_AVERAGES 命令。
    • SHOW STATS 中分别追踪查询数和事务数,原有字段 total_requestsavg_reqavg_query 已被新字段替代。
    • SHOW STATS 中新增 wait_time 字段。
  • 修复
    • 更新 libusual 以支持 OpenSSL 1.1。
    • 不再尝试在 UNIX 套接字上使用 TLS。
    • 解析 pg_hba.conf 时,遇到错误行后继续解析,而非拒绝整个文件。( #118
    • 其他若干 HBA 解析修复。
    • 修复取消查询时的竞争条件(race condition)。( #141
  • 清理
    • auth_user 设置现在也允许在全局范围内配置,而不仅限于单个数据库。( #142
    • 将控制台客户端和服务端编码设置为 UTF8

PgBouncer 1.7.x

2016-02-26 - PgBouncer 1.7.2 - “Finally Airborne”(终于腾空而起)

  • 修复
    • 修复删除过期 pidfile 时的崩溃问题,该问题由 1.7.1 版本引入。
    • 禁用内存清理功能——该功能会破坏接管(takeover)流程,对生产负载也无益。该问题由 1.7.1 版本引入。
    • 接管完成后,等待 pidfile 消失再启动。缓慢的内存清理关闭暴露了已存在的竞争条件。( #113
  • 清理
    • 移除 DBGVER 处理,使构建结果可重现。( #112
    • Antimake:对 $(wildcard) 的文件列表进行排序,较新版本的 gmake 已不再自动排序。( #111
    • 在日志中显示 libssl 版本信息。
    • deb:开启完整的构建安全加固选项。

2016-02-18 - PgBouncer 1.7.1 - “Forward To Five Friends Or Else”(转发给五位好友,否则后果自负)

警告:自 1.7 版本起,当数据库处于事务池模式时,server_reset_query 将不再被执行。这一变化在 1.7 版本的发布说明中未被充分强调。如果你的应用依赖此行为,请使用 server_reset_query_always 恢复旧有行为。

本版本的主要工作是追查一个与 TLS 相关的内存泄漏问题,最终证明该泄漏并不存在。问题实际上出在 Debian/wheezy 中构建的 libssl 版本上——每个连接有约 600k 的固定开销(不存在泄漏),而预期应为 20–30k。使用 TLS 时需留意此问题。

  • 修复
    • TLS:将 sslmode 中的"disabled"重命名为"disable",与 PostgreSQL 的命名保持一致。
    • TLS:client_tls_sslmode=verify-ca/-full 现在会拒绝未提供客户端证书的连接。( #104
    • TLS:client_tls_sslmode=allow/require 在客户端提供证书时会对其进行验证。此前由于证书验证未配置,带有客户端证书的连接会失败。( #105
    • 修复释放数据库时的内存泄漏。
    • 修复 tls_handshake() 中潜在的内存泄漏。
    • 修复 tls_handshake() 中的 EOF 处理问题。
    • 修复 asn1_time_parse 兼容实现中 memset 大小过小的问题。
    • 修复非 TLS 构建(--without-openssl)的编译问题。( #101
    • 修复 Windows 构建中的若干问题。( #100
  • 清理
    • TLS:使用 SSL_MODE_RELEASE_BUFFERS 降低非活跃连接的内存占用。
    • 在退出时释放已分配的内存,便于使用内存泄漏检测工具。
    • 改进 server_reset_query 的文档说明。( #110
    • 在示例配置文件中新增 TLS 相关选项。

2015-12-18 - PgBouncer 1.7 - “Colors Vary After Resurrection”(复活之后,色彩各异)

  • 功能
    • 支持 TLS 连接,以 OpenSSL/LibreSSL 作为后端实现。
    • 支持通过 TLS 客户端证书进行身份认证。
    • 支持 UNIX 套接字上的"peer"认证。
    • 支持基于主机的访问控制文件(类似 Postgres 的 pg_hba.conf),允许为网络连接配置 TLS,为本地连接配置"peer"认证。
  • 清理
    • query_wait_timeout 的默认值设置为 120 秒。原默认值(0)会导致无限排队,实际上没有意义。即当客户端有待执行的查询但尚未分配到服务器连接时,客户端连接将被断开。
    • 默认禁用 server_reset_query_always。现在重置查询仅在会话模式的连接池中执行。
    • pkt_buf 增大至 4096 字节,可改善 TLS 下的性能。此行为可能与负载特性有关,但自 v1.2 起数据包缓冲区已从连接中分离并从池中按需惰性使用,因此该修改是安全的。
    • 支持流水线(pipelining)——统计预期的 ReadyForQuery 数据包数量,避免过早释放服务器连接。修复了 #52
    • 改进 sbuf_loopcnt 逻辑——即使套接字无事件,也保证套接字会被重新处理。这对 TLS 是必要的,因为 TLS 有其自身的缓冲机制。
    • 适配系统测试以兼容现代 BSD 和 MacOS。(Eric Radman)
    • 移除 crypt 认证方式,该方式已过时,PostgreSQL 8.4 起不再支持。
    • 修复不带参数的 --with-cares 配置选项——此前不带参数时该选项无法正常工作。

PgBouncer 1.6.x

2015-09-03 - PgBouncer 1.6.1 - “Studio Audience Approves(观众席报以掌声)”

  • 功能

    • 新增配置项:server_reset_query_always。设置后,在非会话池模式下禁用 server_reset_query。 PgBouncer 引入了按连接池粒度的 pool_mode,但会话池与事务池不应使用相同的重置查询。 事实上,事务池根本不应使用任何重置查询。

      该选项在 1.6.x 中默认开启,但将在 1.7 中关闭。

  • 修复

    • 【安全】移除对 auth_user 的错误赋值(#69)。 当 auth_user 已配置,且客户端请求一个不存在的用户名时, 客户端将以 auth_user 身份登录。这是不合理的。

      CVE-2015-6817

    • 在 handle_auth_response 中跳过 NoticeResponse。否则,服务端较高的日志级别会导致登录失败。

    • console:当 auth_type=any 时,填充 auth_user。否则日志记录可能崩溃(#67)。

    • 多项可移植性修复(OpenBSD、Solaris、OSX)。

2015-08-01 - PgBouncer 1.6 - “Zombies of the future(未来的僵尸)”

  • 功能

    • 从 postgres 数据库加载用户密码哈希。 新增参数:

      auth_user 用于连接同一数据库并获取用户信息的用户名。 也可按数据库单独设置。

      auth_query 以 auth_user 身份执行的 SQL 查询。 默认值:“SELECT usename, passwd FROM pg_shadow WHERE usename=$1”

      (Cody Cutrer)

    • 连接池模式现在支持按数据库和按用户分别配置。 (Cody Cutrer)

    • 支持按数据库和按用户设置连接数上限:max_db_connectionsmax_user_connections。 (Cody Cutrer / Pavel Stehule)

    • 新增 DISABLE/ENABLE 命令,用于阻止新连接接入。 (William Grant)

    • 新增 DNS 后端:c-ares。这是唯一支持所有关键特性的 DNS 后端:支持自动刷新的 /etc/hosts、SOA 查询、大响应(通过 TCP/EDNS+UDP)以及 IPv6。它现在是首选后端,未来可能成为唯一后端,因为维护一套功能残缺的库没有意义。

      注意:c-ares 版本 <= 1.10 存在一个 bug,当启用 IPv6 时会导致 CNAME 支持失效(上游已修复)。作为临时规避措施,c-ares <= 1.10 将仅使用 IPv4。因此,PgBouncer 将在 c-ares >1.10(尚未发布)发布一段时间后,才会放弃其他后端……

    • 在 SHOW CLIENTS/SERVERS 中显示 remote_pid。适用于通过 UNIX socket 连接的客户端,以及通过 TCP 和 UNIX socket 连接的服务端。对于 TCP 服务端,pid 来自取消密钥。

    • 新增独立的配置参数(dns_nxdomain_ttl),用于控制 DNS 否定缓存时间。 (Cody Cutrer)

    • 将客户端主机 IP 地址和端口追加到 application_name 中。 该功能由配置参数 application_name_add_host 控制,默认为 ‘off’。 (Andrew Dunstan)

    • 配置文件新增 %include FILENAME 指令,允许将配置拆分到多个文件中。 (Andrew Dunstan)

  • 清理

    • 日志:用 [] 包裹 IPv6 地址
    • 日志:连接服务端时,显示本地 IP 和端口
    • win32:长参数采用 GNU 风格:–foo
    • 允许主机名中包含数字,始终尝试用 inet_pton 解析
    • 修正 FAQ 中的 deallocate_all()
    • 修正示例配置文件中的错误关键字 (Magnus Hagander)
    • 允许在认证文件中使用注释(以 ‘;’ 开头)。 (Guillaume Aubert)
    • 修正日志消息和注释中的拼写错误。 (Dmitriy Olshevskiy)
  • 修复

    • 修复维护期间启动新连接的问题 (Cody Cutrer)
    • 启动时不重复加载认证文件 (Cody Cutrer)
    • 修复自动数据库(autodb)的失效逻辑
    • IPv6:在监听套接字上设置 IPV6_V6ONLY。
    • win32:不在监听套接字上设置 SO_REUSEADDR。
    • 修复 IPv6 地址的 memcpy 问题
    • 修复取消等待中的客户端连接的问题。 (Mathieu Fenniak)
    • 小 bug 修复:必须检查 calloc 的返回值 (Heikki Linnakangas)
    • 在 PID 文件末尾添加换行符 (Peter Eisentraut)
    • 执行 PAUSE 后,不允许建立新的服务端连接。 (Petr Jelinek)
    • 修复登录时因包头延迟导致的 ‘bad packet’ 错误。 (Michal Trojnara, Marko Kreen)
    • 修复 Coverity 检测到的错误。 (Euler Taveira)
    • 当服务端连接数低于 min_pool 时,禁用 server_idle_timeout(#60) (Marko Kreen)

PgBouncer 1.5.x

2015-04-09 - PgBouncer 1.5.5 - “Play Dead To Win(装死求胜)”

  • 修复
    • 修复远程崩溃问题——无效的数据包顺序导致对 NULL 指针进行查找。 该漏洞不可被利用,仅会造成拒绝服务(DoS)。

2012-11-28 - PgBouncer 1.5.4 - “No Leaks, Potty-Training Successful(无内存泄漏,如厕训练成功)”

  • 修复
    • DNS:修复 getaddrinfo_a() 后端中的内存泄漏。
    • DNS:修复 udns 后端中的内存泄漏。
    • DNS:修复统计数据计算错误。
    • DNS:改进 getaddrinfo_a() 的错误消息处理。
    • 修复 win32 编译问题。
    • 修复 configure 中的编译器依赖性支持检测。
    • 若干文档修复。

2012-09-12 - PgBouncer 1.5.3 - “Quantum Toaster(量子烤面包机)”

  • 严重修复

    • 过长的数据库名称可能导致崩溃。若启用了 autodb,此问题可被远程触发。

      原有检查假定所有名称均来自配置文件,因此使用 fatal() 是安全的。但当启用 autodb 时——即在 [databases] 节中设置 ‘*’——数据库名称可来自网络,从而使远程关闭成为可能。

      CVE-2012-4575

  • 次要功能

    • max_packet_size——用于调整允许通过的最大数据包大小的配置参数。默认值保持不变:(2G-1),但现在可以调小。
    • 当数据包头无法解析时,在日志和错误消息中以十六进制显示该包头。
  • 修复

    • AntiMake:其使用了 $(relpath) 和 $(abspath) 来操作路径名,但当源码树路径包含符号链接时,会导致构建失败。相关代码现已改为仅在纯字符串上操作。
    • console:现在可以使用 SET 命令来设置空字符串值。
    • config.txt:说明所有超时参数均可设置为浮点数。这是 1.4 中引入的隐藏特性。

2012-05-29 - PgBouncer 1.5.2 - “Don’t Chew, Just Swallow(别嚼,直接吞)”

  • 修复
    • 由于失误,reserve_pool_timeout 被以微秒而非秒为单位读取,导致在连接池满时立即激活备用池。现已修正为以秒为单位,与设计意图一致。 (由 Keyur Govande 发现)

2012-04-17 - PgBouncer 1.5.1 - “Abort, Retry, Ignore?(中止,重试,忽略?)”

  • 功能
    • 新增用于调整 UNIX socket 权限的参数:unix_socket_mode=0777unix_socket_group=''
  • 修复
    • 允许服务端变量设置为空字符串——这是使 “application_name” 正常工作所必需的,因为它是唯一没有服务端默认值的参数。
    • 若连接字符串发生变化,要求刷新服务端参数。 此前 PgBouncer 会继续使用旧参数,这在 Postgres 升级后会出现问题。
    • 若 autodb 的连接字符串发生变化,断开旧连接。
    • cf_setint:使用 strtol() 而非 atoi() 来解析整型配置参数,支持十六进制、八进制,并具备更好的错误检测能力。
    • 使用 sigqueue() 检测 union sigval 的存在——修复在 HPUX 上的编译问题。
    • 从 Makefile 中移除 ‘git’ 命令,以避免在纯 tarball 构建时出现随机错误。
    • 为 stats_period 参数补充文档,该参数用于调整统计信息的输出周期。
    • 要求 Asciidoc 版本 >= 8.4,文档与更早版本已不再兼容。
    • 停止对 close() 返回的 EINTR 进行重试。

2012-01-05 - PgBouncer 1.5 - “Bouncing Satisfied Clients Since 2007(自 2007 年起,服务满意的客户端)”

若一个 DNS 名称背后有超过 8 个 IP,现在需要使用 EDNS0 协议进行查询。只有 getaddrinfo_a()/getaddrinfo() 和 UDNS 后端支持它,libevent 1.x/2.x 不支持。要为 libc 启用此功能,请在 /etc/resolv.conf 中添加 ‘options edns0’。

构建现在需要 GNU Make 3.81+。

  • 功能
    • 检测 DNS 回复变化,并使 IP 不再出现在最新回复中的连接失效。 (Petr Jelinek)
    • 基于 DNS 区域 serial 的主机名失效机制。当设置了 dns_zone_check_period 选项后,所有 DNS 区域都会被查询 SOA 记录,一旦 serial 发生变化,所有主机名都将重新查询。这是实现确定性连接失效的必要机制,因为当没有查询发生时,基于查询的失效方式毫无意义。仅在新 UDNS 后端下可用。
    • 新增 SHOW DNS_HOSTS、SHOW DNS_ZONES 命令,用于检查 DNS 缓存。
    • 新增参数:min_pool_size——避免在无负载时断开所有连接。 (Filip Rembialkowski)
    • idle_in_transaction_timeout——若事务空闲时间过长则终止。默认不设置。
    • 新增 libudns DNS 查询后端,比 evdns 功能更丰富。使用 –with-udns 启用。暂不支持 IPv6。
    • KILL 命令,立即断开某一数据库的所有连接。 (Michael Tharp)
    • 迁移至 Antimake 构建系统,使 Makefile 更整洁。构建现需 GNU Make 3.81+。
  • 修复
    • DNS 现在支持 IPv6 主机名。
    • 当 NOTIFY 来自服务端时,不改变连接状态。
    • 若干文档修复。 (Dan McGee)
    • Console:支持使用 "" 进行标识符引用。原先没有接受数据库名称的命令,因此无需引用。
    • Console:允许单词正则表达式以数字开头。使用严格解析器在此处会使事情过于复杂。
    • 不要使已暂停的自动数据库过期。 (Michael Tharp)
    • 在执行 PAUSE 时按需创建自动数据库。 (Michael Tharp)
    • 修复 RESUME 命令打印的错误日志消息。 (Peter Eisentraut)
    • 当数据库连接字符串中有 user= 但无 password= 时,将从 userlist 中获取密码。
    • 在接管(takeover)代码中正确解析 ‘*’。
    • autogen.sh:兼容更旧版本的 autoconf/automake。
    • 修复 win32 上因 mingw/msvc 运行时提供了错误的 basename() 而导致的服务崩溃。现在始终使用兼容版本的 basename()。

PgBouncer 1.4.x

2011-06-16 - PgBouncer 1.4.2 - “Strike-First Algorithm(先发制人算法)”

受影响的操作系统:*BSD、Solaris、Win32。

  • 可移植性修复
    • 将 CFLAGS 传递给链接器。在使用基于 pthread 的 getaddrinfo_a() 回退实现时,这是必要的。
    • lib/find_modules.sh:用 index()+substr() 替换 split(),使其兼容更旧版本的 AWK。
    • <usual/endian.h>:忽略系统定义的 htoX/Xtoh 宏。系统可能只定义了部分宏。
    • <usual/signal.h>:将兼容的 sigval 与兼容的 sigevent 分离
    • <usual/socket.h>:引入 <sys/uio.h> 以获取 iovec
    • <usual/time.h>:在 win32 上改进函数自动检测
    • <usual/base_win32.h>:移除重复的 sigval/sigevent 声明

2011-04-01 - PgBouncer 1.4.1 - “It Was All An Act(一切不过是表演)”

  • 功能

    • 支持监听/连接 IPv6 地址。 (Hannu Krosing)
    • listen_addr 支持多个监听地址。对每个地址调用 getaddrinfo(),因此也可以使用域名。
    • console:向客户端发送 PgBouncer 版本作为 ‘server_version’。
  • 重要修复

    • 在 glibc < 2.9 上禁用 getaddrinfo_a(),因为旧版本会崩溃。

      受影响的主要操作系统:RHEL/CentOS 5.x(glibc 2.5)、Ubuntu 8.04(glibc 2.7)。 Debian/lenny(glibc 2.7)的 getaddrinfo_a() 不会崩溃,但目前没有好的检测方法。

      请在此类系统上使用 libevent 2.x,getaddrinfo_a() 的回退实现不适用于生产系统。另请阅读 README 中新增的"DNS 查询支持"章节,了解 DNS 后端的选取方式。

      (Hubert Depesz Lubaczewski, Dominique Hermsdorff, David Sommerseth)

    • 若使用 libevent 2.x,默认启用 –enable-evdns。

    • 默认开启 tcp_keepalive,与 Postgres 的行为保持一致。 (Hubert Depesz Lubaczewski)

    • 将默认的 server_reset_query 设置为 DISCARD ALL,以默认与 Postgres 兼容。

    • win32:修复 NULL UNIX socket 地址导致的崩溃。 (Hiroshi Saito)

    • 修复 autodb 清理逻辑:旧的清理代码混淆了数据库和连接池——一旦发现一个空连接池,就将该数据库标记为"空闲",这可能导致有活跃用户的数据库被错误终止。

      由 Hubert Depesz Lubaczewski 报告。

  • 修复

    • 通过使用单个并行线程执行查询,使兼容版本的 getaddrinfo_a() 变为非阻塞。
    • 若使用兼容版 getaddrinfo_a(),启用 pthread 编译。
    • release_server 在生命周期断开时漏掉了对 ->last_lifetime_disconnect 的设置。 (Emmanuel Courreges)
    • win32:修复 DOS 换行符的认证文件处理——load_file() 在加载时未考虑文件大小缩减的情况。 (Rich Schaaf)
    • <usual/endian.h>:为编解码函数添加 autoconf 检测,避免在 BSD 上产生冲突。 (James Pye)
    • 当配置文件不存在时不崩溃。 (Lou Picciano)
    • 在噪声级别日志(-v -v)下,DNS 查询失败时不崩溃。 (Hubert Depesz Lubaczewski, Dominique Hermsdorff)
    • 在 find_modules.sh 中使用反引号替代 $(cmd),提升可移植性。 (Lou Picciano)
    • 在 find_modules.sh 中使用 ‘awk’ 替代 ‘sed’,提升可移植性。 (Giorgio Valoti)
    • 启动时记录当前使用的异步 DNS 后端信息。
    • 修复 –disable-evdns 被识别为 ‘yes’ 而非 ’no’ 的问题。
    • 在文档中说明 -R 需要配置 unix_socket_dir。
    • 在 faq.txt 中讨论 server_reset_query。
    • 恢复 slab 分配器中丢失的 memset
    • libusual 中的若干小型可移植性修复。

2011-01-11 - PgBouncer 1.4 - “Gore Code(鲜血淋漓的代码)”

  • 功能

    • 异步 DNS 查询——不再在重载时解析主机名,而是在连接时按需解析,并支持可配置的缓存。 (参见 dns_max_ttl 参数。)

      默认使用 getaddrinfo_a()(glibc)作为后端;若不存在,则通过阻塞式(!)getaddrinfo() 模拟 getaddrinfo_a()。

      若在 configure 时指定 –enable-evdns 参数,则使用 libevent 的 evdns 作为后端。默认不使用,因为 libevent 1.3/1.4 包含有 bug 的实现,只有 libevent 2.0 中的 evdns 看起来是可用的。

    • 新配置变量:syslog_ident,用于调整 syslog 名称。

    • 正式支持 application_name 启动参数。

    • 命令行长选项支持(Guillaume Lelarge)

    • Solaris 可移植性修复(Hubert Depesz Lubaczewski)

    • 新配置变量:disable_pqexec。高度偏执的环境可以使用此选项禁用简单查询协议(Simple Query Protocol),要求应用仅使用扩展查询协议(Extended Query Protocol)。

    • Postgres 兼容性:若启动数据包中的数据库名称为空,则使用用户名作为数据库名。

  • 修复

    • DateStyle 和 TimeZone 服务端参数需要使用精确的大小写。
    • Console:向客户端发送 datetime、timezone 和 stdstr 服务端参数。
  • 内部清理

    • 使用 libusual 库处理底层工具函数。
    • 移除服务端参数的固定长度限制。

PgBouncer 1.3.x

2010-09-09 - PgBouncer 1.3.4 - “Bouncer is always right(保镖永远是对的)”

  • 修复
    • 在连接时应用快速失败(fast-fail)逻辑,使客户端在服务端出现故障时连接时即可收到错误。
    • 不在重载时将自动生成的数据库标记为待检查状态,否则它们将因不在配置中而被删除。
    • 默认忽略 application_name 参数,避免所有 Postgres 9.0 用户都需要自行将其添加到 ignore_startup_parameters= 中。
    • 修正 pg_auth 中的引用处理,其中不使用 ‘'。
    • 改善 console 的错误报告,向用户显示传入的查询。
    • 支持 tv_sec 不是 time_t 类型的操作系统(如 OpenBSD)。
    • 避免在 gcc 4.5 上产生过多警告。

2010-05-10 - PgBouncer 1.3.3 - “NSFW(不宜工作场所浏览)”

  • 改进
    • 使 listen(2) 的参数可配置:listen_backlog。这在允许配置系统最大值的操作系统上非常有用。
    • 改进断开连接的日志消息,显示导致登录失败的用户名或数据库名。
  • 修复
    • 调整快速失败(fast-fail)重启逻辑的位置。旧的逻辑令人恼火,当数据库或用户永久损坏时,即使没有客户端想要登录,也会不断重试。
    • 使日志函数保留旧的 errno,否则在日志级别较高且存在日志问题时,pgbouncer 可能产生异常行为。
    • 增大各种启动相关缓冲区的大小,以处理 EDB 更冗长的启动过程。
    • 检测 V2 协议启动请求,并给出明确的断开原因。

2010-03-15 - PgBouncer 1.3.2 - “Boomerang Bullet(回旋镖子弹)”

  • 修复

    • 新配置变量 query_wait_timeout。若客户端在此秒数内未获得服务端连接,将被终止。

    • 若连接池中没有可用的服务端连接且上次连接尝试失败,则不让客户端连接进入等待队列,而是立即返回错误。

      此修复与上一修复结合,可在数据库宕机时避免不必要的停滞。

    • 在 sbuf.c 中追踪 libevent 状态,以避免重复调用 event_del()。尽管通常是安全的,但似乎并非 100% 可靠。现在我们应能始终明确是否已调用过它。

    • 在 SUSPEND 期间禁用维护操作。否则,在超时较短的情况下,旧的 bouncer 可能在将连接移交后关闭其中几个。

    • 对等待欢迎数据包(即第一个服务端连接)的客户端应用 client_login_timeout。否则,除非设置了 query_timeout,它们可能会无限期等待。

    • win32:在 -regservice 中新增 -U/-P 开关,允许用户选择运行服务所用的账户。旧的在 Local Service 和 Local System 之间自动选择的逻辑不够可靠。

    • console:移除文本列末尾的 \0。由于 C 客户端对此无感,该问题不易察觉。

    • 文档改进。(Greg Sabino Mullane)

    • 澄清若干登录相关的日志消息。

    • 将连接池发出的错误(通常在断开时)的日志级别从 INFO 提升至 WARNING,因为它们表示存在问题。

    • 将 query_timeout 的日志消息更改为 “query timeout”。

2009-07-06 - PgBouncer 1.3.1 - “Now fully conforming to NSA monitoring requirements(现已完全符合 NSA 监控要求)”

  • 修复
    • 修复 sbuf_loopcnt 相关问题,该问题可能导致连接挂起。若查询或结果长度接近 (pktlen*sbuf_loopcnt)(默认 10k)的整数倍,连接可能会停留在等待更多数据的状态,而这些数据永远不会到来。
    • 使数据库重新配置立即生效。此前在 SIGHUP 后旧连接可能被复用。
    • 修复 SHOW DATABASES 因列添加而损坏的问题。
    • 当 “auth_type=any” 时,console 访问因 pgbouncer 丢弃了用户名而被禁用。修复:若 “auth_type=any”,允许任何用户以管理员身份访问 console。
    • 修复错误的 CUSTOM_ALIGN 宏。幸运的是,若操作系统已定义了 ALIGN 宏,该宏则不会被使用,因此该 bug 似乎从未在实际中触发。
    • win32:始终调用 WSAStartup(),而不仅在守护进程模式下调用,因为配置解析也需要解析主机名。
    • win32:在服务命令行中为配置文件名加上引号,以支持路径中包含空格。可执行文件路径似乎因某种 win32 机制而无需此处理。
    • 将 STATS 添加到 SHOW HELP 文本中。
    • doc/usage.txt:console 结果中的时间单位是微秒,不是毫秒。

2009-02-18 - PgBouncer 1.3 - “New Ki-Smash Finishing Move(全新气功波终结技)”

  • 功能

    • IANA 已将 6432 端口分配为 PgBouncer 的官方端口。因此,默认端口号已更改为 6432。现有的个人用户无需更改,但若您打包分发 PgBouncer,请将包的默认端口改为此官方端口。

    • 动态数据库创建(David Galoyan)

      现在可以定义名称为 “*” 的数据库。若已定义,其连接字符串将用于所有未定义的数据库。主要适用于测试/开发环境。

    • Windows 支持(Hiroshi Saito)

      PgBouncer 现可运行于 Windows 2000+。命令行用法保持不变,但不能以守护进程运行,也不能进行在线重启。要作为服务运行,请在配置中定义 service_name 参数,然后执行:

      > pgbouncer.exe config.ini -regservice
      > net start SERVICE_NAME
      

      停止并注销服务:

      > net stop SERVICE_NAME
      > pgbouncer.exe config.ini -unregservice
      

      要使用 Windows 事件日志,需要先注册事件 DLL:

      > regsrv32 pgbevent.dll
      

      之后即可在配置中设置 “syslog = 1”。

  • 次要功能

    • 配置文件中的数据库名称现在可以使用标准 SQL 标识符引用方式加引号,以支持名称中包含非标准字符。

    • 新可调参数:reserve_pool_sizereserve_pool_timeout。当连接池中有客户端等待时间超过 reserve_pool_timeout 秒时,reserve_pool_size 指定可向连接池添加的额外连接数。也可通过连接变量 reserve_pool 按连接池单独设置。

    • 新可调参数 sbuf_loopcnt,用于限制在单个套接字上花费的时间。

      在某些情况下——如 SMP 服务器、本地 Postgres 和快速网络——pgbouncer 可以在两端都不阻塞的情况下多次执行 recv()->send() 循环。但这意味着其他连接将长时间停滞。为使处理更加公平,限制对单个套接字执行 recv()->send() 的次数。若计数达到限制,则继续处理其他套接字,该套接字的处理将在下一个事件循环中恢复。

      感谢 Alexander Schocke 的报告和测试。

    • crypt() 认证现为可选,因为它已从 Postgres 中移除。若操作系统不提供它,pgbouncer 也能正常工作。

    • 在日志时间戳中添加毫秒。

    • 用更精简的实现替换旧的 MD5 实现。

    • 更新 ISC 许可证,加入 FSF 的澄清说明。

  • 修复

    • 若 event_del() 报告失败,则继续执行清理操作。 此前 pgbouncer 会重试,以防失败是由 ENOMEM 引起的。但这导致了包含无限重复的日志洪泛,看来 libevent 不喜欢这种做法。

      为何 event_del() 第一次就报告失败,至今仍是个谜。

    • –enable-debug 现在仅控制是否从二进制文件中剥离调试信息,不再影响 -fomit-frame-pointer,因为那样做是危险的。

    • 修复 include 顺序,否则系统头文件可能在内部头文件之前被引入。这对新的 md5.h 头文件来说是个问题。

    • 在 .tgz 中包含 COPYRIGHT 文件……


PgBouncer 1.2.x

2008-08-08 - PgBouncer 1.2.3 - “Carefully Selected Bytes(精心挑选的字节)”

  • 修复
    • 禁用在 BSD 上无法正常工作的 SO_ACCEPTFILTER 代码。
    • 在 tgz 中包含示例 etc/userlist.txt。
    • 在递归调用中使用 ‘$(MAKE)’ 而非 ‘make’(Jorgen Austvik)
    • 定义 _GNU_SOURCE,否则 glibc 形同虚设。
    • 允许 libevent 1.1 通过链接测试,以便稍后报告"需要 1.3b+"。
    • 检测并移除过期的 pidfile。

感谢 Devrim GUNDUZ 和 Bjoern Metzdorf 的问题报告和测试。

2008-08-06 - PgBouncer 1.2.2 - “Barf-bag Included(随附呕吐袋)”

  • 修复
    • 移除 ‘drop_on_error’,这是个糟糕的设计。它最初是作为 Postgres 中破损的计划缓存行为的变通方案而添加的,但在某些查询总是返回错误的常见场景下,可能会造成损坏。

2008-08-04 - PgBouncer 1.2.1 - “Waterproof(防水)”

  • 功能
    • 新参数 drop_on_error——若服务端抛出错误,该连接在客户端使用完毕后将被丢弃而非复用。这是为了刷新计划缓存,即便在 8.3 中自动刷新也无法正常工作。默认值为 1。
  • 修复
    • SHOW SOCKETS/CLIENTS/SERVERS:若套接字无缓冲区时不崩溃。
    • 修复当 suspend_timeout 触发时 SUSPEND 进入无限循环的问题。
  • 小型清理
    • 使用 <sys/uio.h> 获取 ‘struct iovec’。
    • 在 RESUME/SIGUSR2 时取消关闭操作(由 SIGINT 触发),否则下次 PAUSE 时还会触发。
    • 若 console 操作被取消,输出正确的日志消息。

2008-07-29 - PgBouncer 1.2 - “Ordinary Magic Flute(普通魔法长笛)”

PgBouncer 1.2 现在要求 libevent 版本 1.3b 或更高。更旧的 libevent 版本在新的重启代码下会崩溃。

  • 功能

    • 命令行选项(-u)和配置参数(user=),支持在启动时切换用户。同时,pgbouncer 现在拒绝以 root 身份运行。

      (Jacob Coby)

    • 更具描述性的使用说明文本(-h)。(Jacob Coby)

    • 新的数据库选项:connect_query,允许在新连接投入使用前执行一条查询。

      (Teodor Sigaev)

    • 新配置变量 ignore_startup_parameters,允许忽略启动数据包中的额外参数。默认情况下只允许 ‘database’ 和 ‘user’,其他所有参数均会触发错误。这是为了兼容 JDBC 强制在启动数据包中设置 ’extra_float_digits=2’ 的行为。

    • syslog 日志记录:新增参数 syslog=0/1 和 syslog_facility=daemon/user/local0。

    • 更平滑的在线重启(-R)

      • 将 FD 加载移至 fork 之前,使其日志输出到控制台,且可用 ^C 取消。

      • fork 之后保持 SHUTDOWN 状态,使 ^C 操作更安全。

      • 尝试通过 connect() 连接 UNIX socket,以检查是否有进程在监听。现在即使之前没有运行中的进程,也可以使用 -R。若之前有进程运行,但未使用 -R,则启动失败。

    • 新控制台命令:

      • SHOW TOTALS:显示统计摘要(与日志内容一致)及内存使用情况。

      • SHOW ACTIVE_SOCKETS:类似 show sockets,但仅过滤出活跃的套接字。

  • 次要功能

    • suspend_timeout——断开停滞连接和长时间登录的连接。为重启提供额外安全保障。

    • 当远端数据库在登录时抛出错误,将通知客户端。

    • 从配置中删除数据库并重载配置后,该数据库的所有连接将被终止并移除。

    • 在 console 的 SHOW/SET 命令中伪造部分参数,使其更接近 Postgres。这是为了让 psycopg 能够连接到 console。 (client_encoding/default_transaction_isolation/datestyle/timezone)

    • server_lifetime=0 的行为改为:在首次使用后立即断开服务端连接。此前 “0” 使 PgBouncer 忽略服务端连接的存活时间。由于该行为未在文档中说明,应该没有用户依赖此行为。

    • 内部改进:

      • 数据包缓冲区现在按需分配并复用,内存使用量将大幅降低。这也使得在大量连接时使用较大的 pktbuf 成为现实。

      • 大量错误处理改进,PgBouncer 现在应能在内存不足(OOM)时优雅降级。

      • 使用 slab 分配器进行内存管理。

      • 大量代码清理。

  • 修复

    • 每个事件循环只处理一个 accept(),当连接请求量较大时可能导致连接积压。现在始终将监听套接字完全排空,应可解决此问题。
    • 处理来自 connect() 的 EINTR。
    • 使 configure.ac 兼容 autoconf 2.59。
    • Solaris 兼容性修复(Magne Maehre)

PgBouncer 1.1.x

2007-12-10 - PgBouncer 1.1.2 - “The Hammer(铁锤)”

  • 功能
    • server_lifetime 导致的断开连接现在按(server_lifetime / pool_size)秒的间隔分散执行,以避免 pgbouncer 造成重连风暴。
  • 修复
    • 在线升级 1.0 -> 1.1 时的问题:
      • 1.0 不追踪服务端参数,因此它们保持为 NULL,而 1.1 未预期此情况并发生崩溃。
      • 若服务端参数未知,但客户端参数已设置,则发出 SET 命令,而非报错。
    • 移除意外遗留在代码中的 INFO 级别临时调试语句,它们污染了日志。
    • 修复 debian/changelog
  • 清理
    • 重新排列 SBuf 结构体字段,使缓冲区对齐更优。

2007-10-26 - PgBouncer 1.1.1 - “Breakdancing Bee(霹雳舞蜜蜂)”

  • 修复
    • 服务端参数缓存可能保持未初始化状态,导致不必要的 SET 操作。这在不允许修改 standard_conforming_strings 的 8.1 版本上引发了问题。 (感谢 Dimitri Fontaine 的报告和测试。)
    • 若干文档修复。
    • 在 .tgz 中包含 doc/fixman.py。

2007-10-09 - PgBouncer 1.1 - “Mad-Hat Toolbox(疯帽子工具箱)”

  • 功能

    • 追踪以下服务端参数:

      client_encoding  datestyle, timezone, standard_conforming_strings
      
    • 数据库连接字符串增强:

      • host= 接受主机名
      • host= 接受自定义 UNIX socket 路径
      • 接受带引号的值:password=’ asd’‘foo’
    • 新配置变量:server_reset_query,在连接释放后立即发送。

    • 新配置变量:server_round_robin,用于在 LIFO 和轮询(RR)之间切换。

    • 向空闲连接发送取消包不再断开该连接。

    • 在 SUSPEND / PAUSE 时,psql 的 ^C 取消操作现在可以正常工作。

    • 启动时打印 FD 限制。

    • 暂停时尽快对齐到数据包边界。

    • 将 ’timezone’ 添加到数据库参数中。

    • 使用长期持有的日志文件描述符,在 SIGHUP / RELOAD 时重新打开。

    • 在 SHOW SERVERS/CLIENTS/SOCKETS 中显示本地连接端点信息。

  • 代码清理

    • 更多调试日志消息包含套接字信息。
    • 移除魔法数字,清理错误消息。(David Fetter)
    • 为当前包信息引入包装结构体,大幅降低代码复杂度。
  • 修复

    • 改进无效包头的检测。
    • auth_file 的修改时间检测存在 bug,导致 pgbouncer 过于频繁地重新加载它。

PgBouncer 1.0.x

2007-06-18 - PgBouncer 1.0.8 - “Undead Shovel Jutsu(不死铲子术)”

  • 修复
    • 修复取消包(cancel packet)处理中的崩溃问题。(psql 中的 ^C)
  • 功能
    • PAUSE ; RESUME ; 现在可以正常使用。
    • 清理 console 命令解析。
    • 禁用开销较大的列表内断言检查。

2007-04-19 - PgBouncer 1.0.7 - “With Vitamin A-Z(含维生素 A-Z)”

  • 修复
    • 在发送过程中多个错误/通知数据包与 send() 阻塞交叠时触发了断言。通过彻底移除刷新逻辑来修复此问题。由于 pgbouncer 不主动缓冲任何内容,刷新逻辑实际上不必要。这是使用 MSG_MORE 将缓冲推送到内核时代遗留下来的。
    • 另外,避免在发送解除阻塞时调用 recv() 逻辑。
    • admin_users 和 stats_users 的列表搜索代码对部分匹配处理有误,已修复。
    • 将 UNIX socket 对端 UID 获取标准化为使用 getpeereid()。

2007-04-12 - PgBouncer 1.0.6 - “Daily Dose(每日剂量)”

  • 修复
    • “在接管期间禁用维护"的修复可能导致维护被彻底禁用,已修复。
    • FreeBSD 编译修复:在 FreeBSD 上,<sys/ucred.h> 需要先引入 <sys/param.h>。 感谢 Robert Gogolok 的报告。

2007-04-11 - PgBouncer 1.0.5 - “Enough for today(今天到此为止)”

  • 修复
    • 修复在线重启(online-restart)的若干 bug:
      • 为空闲服务端设置 ->ready 标志。
      • 移除 use_client_socket() 中的过时代码。
      • 在接管期间禁用维护操作。

2007-04-11 - PgBouncer 1.0.4 - “Last ’last’ bug(最后一个’最后’的 bug)”

  • 修复
    • 来自空闲服务端的 Notice 将服务端连接标记为脏状态,而 release_server() 未预期此情况。通过直接丢弃此类通知来修复。

2007-04-11 - PgBouncer 1.0.3 - “Fearless Fork(无畏的 Fork)”

  • 修复

    • 登录路径中部分错误处理缺失,导致该处的连接断开可能触发断言。
    • 清理 sbuf.c 中的断言,以便更早发现问题。
    • 在 Assert() 触发时生成 core dump。
  • 新增内容

    • 新配置变量:log_connectionslog_disconnectionslog_pooler_errors,用于控制日志噪声的开关。
    • 配置变量:client_login_timeout,用于终止登录阶段停滞的连接,避免其阻塞 SUSPEND 进而影响在线重启。

2007-03-28 - PgBouncer 1.0.2 - “Supersonic Spoon(超音速汤匙)”

  • 修复
    • libevent 可能在同一事件循环内报告一个已删除的事件。通过在一个事件循环内避免套接字复用来解决。
    • 从 disconnect_client() 调用 release_server() 时,未检查数据包是否实际已发送。

2007-03-15 - PgBouncer 1.0.1 - “Alien technology(外星科技)”

  • 修复

    • 混用缓存时间与非缓存时间,加上无符号的 usec_t typedef,导致了虚假的 query_timeout 错误。
    • 修复套接字从发送等待中唤醒后偶发停滞的罕见情况。
    • 更公平的服务端连接排队机制。此前,新查询可能比旧查询更早获得服务端连接。
    • 延迟服务端释放,直至所有数据确保已发送完毕。
  • 功能

    • SHOW SOCKETS 命令,提供连接状态的详细信息。
    • 在日志中加入 PgSocket 指针,便于追踪单个连接。
    • 在 console 中,允许用 SELECT 替代 SHOW。
    • 若干代码清理。

2007-03-13 - PgBouncer 1.0 - “Tuunitud bemm(调校过的宝马)”

  • 首次公开发布。

7 - 社区

PgBouncer 社区资源、教程与支持

来源: https://www.pgbouncer.org/community.html


教程


支持

8 - 常见问题解答

PgBouncer 常见问题解答

原始页面: https://www.pgbouncer.org/faq.html


如何连接到 PgBouncer?

PgBouncer 扮演 PostgreSQL 服务器的角色,只需将客户端指向 PgBouncer 端口即可。


如何在多个服务器之间实现查询负载均衡?

PgBouncer 没有内置的多主机配置功能,但可以通过外部工具实现:

  1. DNS 轮询。在一个 DNS 名称后面配置多个 IP。PgBouncer 不会在每次新建连接时查询 DNS,而是缓存所有 IP 并在内部进行轮询。注意:若一个名称后有 8 个以上的 IP,则 DNS 后端必须支持 EDNS0 协议。详情参见 README。

  2. 使用 TCP 连接负载均衡器。 LVSHAProxy 都是不错的选择。在 PgBouncer 一侧,建议适当减小 server_lifetime 的值并开启 server_round_robin:默认情况下,空闲连接按 LIFO 算法复用,在需要负载均衡时效果可能不佳。


如何实现故障转移?

PgBouncer 没有内置的故障转移主机配置或检测功能,可借助外部工具实现:

  1. DNS 重新配置:当 DNS 名称对应的 IP 地址发生变化时,PgBouncer 将重新连接到新服务器。可通过两个配置参数进行调整:dns_max_ttl 控制单个主机名的生存时间,dns_zone_check_period 控制查询区域 SOA 变更的频率。若区域 SOA 记录发生变化,PgBouncer 将重新查询该区域下的所有主机名。

  2. 向配置文件写入新主机并让 PgBouncer 重新加载:发送 SIGHUP 信号或在控制台执行 RELOAD 命令。PgBouncer 会检测到主机配置变更并重新连接到新服务器。

  3. 使用 RECONNECT 命令。适用于上述两种方案都不适用的情况,例如使用前述的 HAProxy 在 PgBouncer 下游路由连接时。RECONNECT 会重新打开所有服务端连接,请在其他组件更改连接路由信息后执行该命令。


如何在会话池化模式下使用预处理语句?

在会话池化模式下,重置查询必须清理旧的预处理语句。可通过设置 server_reset_query = DISCARD ALL; 或至少 DEALLOCATE ALL; 来实现。


如何在事务池化模式下使用预处理语句?

自 1.21.0 版本起,PgBouncer 可在事务池化模式下追踪预处理语句,并确保它们在关联的服务端连接上即时准备好。要启用此功能,需将 max_prepared_statements 设置为非零值。详情请参阅 max_prepared_statements 的文档。

如果使用 PHP/PDO,根据其版本可能与 PgBouncer 的预处理语句支持不兼容(#991)。PHP/PDO 仅在使用 PHP 8.4+ libpq 17 时才兼容。因此,对于使用旧版本的环境,建议升级或在客户端禁用预处理语句。

在 JDBC 中禁用预处理语句

对于 JDBC,正确的做法是在连接字符串中添加 prepareThreshold=0 参数。

在 PHP/PDO 中禁用预处理语句

要禁用服务端预处理语句,必须将 PDO 属性 PDO::ATTR_EMULATE_PREPARES 设置为 true。可在连接时设置:

$db = new PDO("dsn", "user", "pass", array(PDO::ATTR_EMULATE_PREPARES => true));

或在连接后设置:

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

如何在不断开连接的情况下升级 PgBouncer?

可以按照 SHUTDOWN WAIT_FOR_CLIENTS 文档章节中描述的流程执行滚动重启。


如何查看哪个客户端对应哪个服务端连接?

在控制台使用 SHOW CLIENTSSHOW SERVERS 命令。

  1. 使用 ptrlink 将本地客户端连接映射到服务端连接。

  2. 使用客户端连接的 addrport 识别来自客户端的 TCP 连接。

  3. 使用 local_addrlocal_port 识别到服务端的 TCP 连接。


PgBouncer 应安装在 Web 服务器还是数据库服务器上?

视情况而定。

当使用短连接时,将 PgBouncer 安装在 Web 服务器上较为合适,可以最大程度降低连接建立的延迟(TCP 连接在可用前需要几次数据包往返)。当有大量不同主机(如多台 Web 服务器)连接到数据库时,将 PgBouncer 安装在数据库服务器上更为合适,可统一优化这些连接。

也可以在 Web 服务器和数据库服务器上同时安装 PgBouncer。但这样做的缺点是每经过一个 PgBouncer 节点,每条查询都会增加一定的延迟。

最终,需要根据性能需求测试哪种模式效果更好。还应考虑在 Web 服务器或数据库服务器发生故障时,PgBouncer 的安装位置将如何影响应用程序的故障转移。