PG 连接被切断?5秒钟查出"凶手"
PostgreSQL 重磅更新:连接被切断?5秒钟查出"凶手"
一个 DBA 的深夜惊魂
凌晨2点,你被报警声吵醒。
生产数据库大量连接中断,错误日志清一色刷着"terminating connection due to administrator command"。你抓起手机开始排查:是运维同事在执行维护?还是监控脚本在清理空闲连接?或者——某位误操作的开发者闯了祸?
你翻遍日志,一头雾水。
"administrator command",哪个 administrator?谁的命令?
这个困扰 PostgreSQL DBA 多年的难题,终于有了官方解。
1. 发生了什么?
就在最近,PostgreSQL 社区合并了一个看似不起眼、却直击痛点的 commit(55890a9)。
它的名字叫信号溯源(Signal Source Attribution)。
翻译成人话就是:以后谁的连接被断了,数据库会明确告诉你——是哪个进程(PID)、哪个用户(UID)动的手。
看个对比:
改进前:
FATAL: terminating connection due to administrator command
——你知道被枪杀了,但不知道是谁开的枪。
改进后:
FATAL: terminating connection due to administrator command
DETAIL: Signal sent by PID 67890, UID 1005.
——枪号、射手,证据链完整。
2. 技术原理(3分钟看懂)
不想看代码的同学,直接跳到下一节。
PostgreSQL 底层用 SIGTERM 信号来终止后端连接。以往信号里只带着"我要杀你"的信息,但不告诉你谁发的。
这次改动利用了 Unix 的 SA_SIGINFO 扩展——这个能力可以让信号携带"发射者身份"。
简单说,信号里现在多了两个字段:
si_pid:发信号那个进程的 ID si_uid:发信号那个进程所属用户的 ID
当后端进程被 SIGTERM 放倒时,日志就会多打印一行,明确告诉你"凶手"的 PID 和 UID。
支持哪些平台?
Linux、FreeBSD 等主流 Unix 系统都支持。Windows 用户暂时无缘这个功能(微软不给力)。
3. 三大真实场景
3.1 多 DBA 共管环境——谁动了我的连接?
场景还原:
公司数据库由 A、B 两个 DBA 团队共管,大家都用 pg_terminate_backend 权限。某天,某个核心业务的连接被误杀,业务方炸锅,两个团队互相甩锅。
有了信号溯源之后:
-- 查日志
DETAIL: Signal sent by PID 67890, UID 1005.
-- 顺着 PID 查进程
$ ps aux | grep 67890
# 定位到是一套监控脚本
-- 顺着 UID 查用户
$ id 1005
# 确认是 dba_user_zhang 在执行自动化巡检
30秒定责,锅甩得清清楚楚。
3.2 自动化运维——哪个工具在"捣鬼"?
很多公司用多套自动化工具管理 PostgreSQL:pgBadger 做分析、pgCluu 做审计、Patroni 做高可用……
某个后台会话突然被终止,日志只说"管理员命令",你得一个个工具去排查。
现在?
DETAIL: Signal sent by PID 31415, UID 0.
UID 为 0?说明是 root 或系统服务发起的。结合 systemd journal 直接定位是哪个服务,一分钟锁定目标。
3.3 Kubernetes 滚动更新——是 K8s 在升级,还是人为误删?
在 K8s 环境里,kubectl delete pod 会给容器发 SIGTERM。
以前日志看不出是滚动更新还是人为删除,现在一目了然:
DETAIL: Signal sent by PID 1, UID 0.
PID 1 在容器里通常是 init 进程(K8s 的 kubelet)。结合 K8s events,立刻能确认是滚动更新触发的正常重启,还是运维误操作。
4. 对 DBA 有多实用?
5. 未来可期
这个功能目前只追踪 SIGTERM(即 pg_terminate_backend)。
社区已经在讨论扩展到:
pg_cancel_backend()的溯源将 UID 转换为可读的用户名 pg_stat_activity里增加信号来源字段
期待后续版本。
6. 写在最后
这个改动看似小,但解决的是一个高频痛点。
我见过太多 DBA 凌晨被报警叫醒,然后花几个小时在日志里"考古"——就为了回答一个问题:到底是谁干的?
现在,答案就在日志里。
你遇到过"连接被断却查不出凶手"的情况吗?欢迎留言聊聊你是怎么排查的。
觉得有用?转发给需要的朋友。