You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PGbouncer占用template1连接致无法创建数据库的问题排查与解决

问题描述

在3台PostgreSQL服务器前端部署PGbouncer后,连接池功能运行正常,但执行创建数据库操作时,出现template1被占用、无法创建的错误。通过pg_activity查询发现PGbouncer服务器持有template1的活跃连接,执行SHOW CLIENTS确认无其他外部客户端连接,说明是PGbouncer自身持有该连接;SHOW POOLS结果显示template1存在连接池且有空闲连接:

pgbouncer=# show pools;
 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 | sv_tested | sv_login | maxwait | maxwait_us | pool_mode
-----------+-----------+-----------+------------+----------------------+-----------------------+-----------+------------------+-------------------+---------+---------+-----------+----------+---------+------------+-----------
 pgbouncer | pgbouncer |         1 |          0 |                    0 |                     0 |         0 |                0 |                 0 |       0 |       0 |         0 |        0 |       0 |          0 | statement
 root      | root      |         0 |          0 |                    0 |                     0 |         0 |                0 |                 0 |       0 |       1 |         0 |        0 |       0 |          0 | session
 template1 | postgres  |         0 |          0 |                    0 |                     0 |         0 |                0 |                 0 |       1 |       0 |         0 |        0 |       0 |          0 | session
(3 rows)

当前PGbouncer配置如下:

pgbouncer.ini

;;; This is an almost minimal starter configuration file that only
;;; contains the settings that are either mandatory or almost always
;;; useful.  All settings show their default value.

[databases]
* = host=localhost port=9999

[pgbouncer]
;; required in daemon mode unless syslog is used
;logfile =
;; required in daemon mode
pidfile = /usr/local/pgbouncer/pgbouncer.pid

syslog = 1

;; set to enable TCP/IP connections
listen_addr = *
;; PgBouncer port
listen_port = 5432

;; some systems prefer /var/run/postgresql
;unix_socket_dir = /tmp

;; change to taste
auth_type = trust
;; probably need this
auth_file = /usr/local/pgbouncer/etc/userlist.txt

;; pool settings are perhaps best done per pool
;pool_mode = session
;default_pool_size = 20

;; should probably be raised for production
max_client_conn = 10000

ignore_startup_parameters = extra_float_digits

admin_users = pgbouncer,postgres,root
原因分析
  1. PGbouncer连接池机制:当前template1使用session池模式,这种模式下客户端断开连接后,PGbouncer会将后端连接保留为空闲状态(sv_idle=1),等待下一个客户端复用,不会立即关闭。
  2. CREATE DATABASE的排他锁要求:执行CREATE DATABASE时,PostgreSQL需要对template1获取排他锁(ACCESS EXCLUSIVE),而PGbouncer持有的空闲连接虽无活跃操作,但仍占据着template1的连接,导致无法获取排他锁,从而报错。
解决方法

临时解决:释放template1的空闲连接

登录PGbouncer管理控制台,执行以下命令强制关闭template1池的所有空闲连接:

KILL POOL template1;

执行后再次查询SHOW POOLS,确认template1的sv_idle变为0,此时即可正常执行CREATE DATABASE操作。

长期优化:配置PGbouncer避免占用template1

方法1:禁止PGbouncer池化template1连接

在pgbouncer.ini的[databases]段添加template1的专属配置,将其连接池大小设为0,这样PGbouncer不会为template1创建池化连接,所有连接用完即关:

[databases]
* = host=localhost port=9999
template1 = host=localhost port=9999 pool_size=0

修改后重启PGbouncer生效。

方法2:设置空闲连接超时

在pgbouncer.ini的[pgbouncer]段添加server_idle_timeout参数,让空闲连接在指定时间后自动关闭,避免长期占用:

[pgbouncer]
server_idle_timeout = 30  # 单位:秒,可根据实际情况调整

修改后重启PGbouncer生效。

操作建议

创建数据库时,建议直接连接到PostgreSQL实例(绕过PGbouncer),这样可以完全避免池化连接的干扰,操作完成后再通过PGbouncer访问业务数据库。

内容的提问来源于stack exchange,提问作者Dan Sherwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 03:15:20