navicat 无连接池机制,所谓“连接池耗尽”实为 postgresql 的 max_connections 配额超限;其每次操作均新建 tcp 连接,排查需查 pg_stat_activity 和 max_connections 设置,并清理 idle in transaction 等无效连接。

Navicat根本没有连接池,所谓“连接池耗尽”是数据库服务端超限
Navicat 是纯客户端工具,每次点击连接、打开新查询标签页、执行刷新操作,都会新建一条 TCP 连接并保持到 PostgreSQL 服务端。它不维护任何连接复用或池化机制。因此,“连接池满”这个说法本身是误导性的——真正被耗尽的是 PostgreSQL 的 max_connections 配额。
典型表现是 Navicat 弹出类似 too many connections(MySQL 风格错误)或 remaining connection slots are reserved for non-replication superuser connections(PostgreSQL 风格错误),但 Navicat 自身内存、CPU、线程数完全正常。
排查必须绕过 Navicat 的错误提示,直接查服务端真实状态:
- 登录数据库服务器,执行
SELECT count(*) FROM pg_stat_activity;查当前活跃连接数 - 执行
SELECT setting FROM pg_settings WHERE name = 'max_connections';确认上限值 - 重点检查
state = 'idle in transaction'的连接:它们占着 slot 却不干活,常因未提交事务或长查询卡住
如何快速定位哪些 Navicat 标签页在“吃掉”连接
PostgreSQL 的 pg_stat_activity 能反向追溯每个连接的来源。Navicat 发起的连接通常带有可识别特征:
-
application_name字段多为Navicat或空(旧版),可通过SELECT application_name, client_hostname, backend_start FROM pg_stat_activity ORDER BY backend_start DESC LIMIT 10;快速筛选 - 若使用了多个 Navicat 连接配置,
datname(数据库名)和usename(用户名)能帮你对应到具体项目或环境 - 长时间
state = 'idle'但backend_start很早的连接,大概率是用户打开了标签页后忘记关闭
注意:client_hostname 在 Docker 或 NAT 环境下可能显示为内网 IP 或 localhost,此时需结合 client_addr(客户端真实 IP)判断来源机器。
为什么改了 pg_hba.conf 还连不上?先确认是不是连接数真满了
很多人一遇到连接失败就猛改 pg_hba.conf,结果白忙活。因为 pg_hba.conf 控制的是“谁被允许认证”,而连接数超限发生在认证前的资源分配阶段——PostgreSQL 根本不会给你机会走到认证那步。
所以,当你修改完 pg_hba.conf 并执行 SELECT pg_reload_conf(); 后仍连不上,请立即验证是否已达 max_connections 上限:
- 如果
pg_stat_activity返回的连接数 ≥max_connections,说明问题与认证无关,优先 kill 闲置连接或调高上限 - 临时释放连接可用
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND now() - backend_start > interval '5 minutes'; - 永久解决需调整应用行为:禁用 Navicat 的自动刷新、关闭不用的查询标签页、设置
idle_in_transaction_session_timeout
容易被忽略的“隐性连接源”:Navicat 的后台任务
除了你手动打开的标签页,Navicat 还会在后台发起连接用于:
- 对象浏览器自动刷新(右键数据库 → “刷新” 或启用“自动刷新”选项)
- 连接测试时未关闭的预览窗口(如双击表名打开数据预览,即使没点“确定”也会建连)
- SQL 文件执行后未关闭的结果页(尤其批量执行脚本时)
这些连接不会显示在主界面显眼位置,但会持续占用 max_connections。建议在排查期关闭所有自动刷新功能,并用 pg_stat_activity 对比 Navicat 启动前后连接数变化来识别它们。











