删除生产主库指定数据库后PostgreSQL从库频繁报库不存在,如何排查请求来源
定位持续请求已删除PostgreSQL数据库的来源实操
前置说明
这类针对不存在数据库的连接请求,会在PostgreSQL会话初始化阶段直接被拒绝,根本不会进入可查询的pg_stat_activity视图,纯靠查活动会话是抓不到来源的。
步骤1:在线开日志拿源IP,全程不重启实例
用postgres超级用户连到任意存活的数据库(比如默认的postgres系统库),执行以下调整,都是支持SIGHUP重载的参数,完全不需要重启实例:
- 执行
ALTER SYSTEM SET log_connections = 'on';打开连接日志,会记录每一次连接请求的源IP、源端口、操作用户 - 执行
ALTER SYSTEM SET log_error_verbosity = 'verbose';确保报错信息带全上下文 - 执行
SELECT pg_reload_conf();让配置即时生效 - 等3-5分钟(按3.2秒一次的频率,足够产生几十条日志),在日志里找目标报错行的上下相邻记录,直接就能拿到配对的源IP。对应日志格式参考:
LOG: connection received: host=10.0.0.5 port=38271
FATAL: database "dbname" does not exist - 定位完成后记得把
log_connections改回原有配置,避免不必要的日志写入量。
步骤2:抓包快速锁定发起端
如果找日志路径太麻烦,直接在数据库服务器上抓网络包,完全不侵入业务:
- 用root权限执行tcpdump,不做域名解析,只抓数据库默认5432端口的流量,抓够100个包就自动停止,避免长期抓包消耗性能:
tcpdump -i any port 5432 -nn -c 100 - 输出的远端IP列表里,那个固定3秒左右出现一次的地址,就是发起异常请求的源头。
- 拿到源IP后,登录对应主机执行
ss -tunp | grep :5432,直接查到发起连接的进程PID、对应的可执行文件路径,顺藤摸瓜找到残留的配置项。
高频排查方向
按生产环境的出现概率排序,这类固定间隔3秒左右的重试请求基本来自:
- 如果报错出现在从库的日志里,第一优先级排查从库本地的配置——本地进程发起的请求不需要跨网络,是最容易被忽略的来源。
- PgBouncer、PgPool这类连接池的残留配置:这类工具的连接重试间隔默认就是2-5秒,只要配置文件里还保留着已删除数据库的连接条目,就会持续发请求重试。
- 逻辑复制的残留作业:之前针对被删除数据库配置过的逻辑订阅、同步作业,主库删库后订阅端会按固定间隔轮询目标库,触发不存在的报错。
- 常驻进程的旧连接串:没清理干净的旧监控探针、后台脚本、临时调试进程,一直带着旧的数据库连接串发起重试。
- 主从切换后的残留节点:老主库上的本地作业没有感知到角色切换,还按原配置持续连接当前的主库。
内容的提问来源于stack exchange,提问作者Darshan Shah
相关产品推荐
相关产品推荐

