PostgreSQL 锁监控:先找阻塞链,再决定处理方式

背景 被阻塞的 SQL 不一定是罪魁祸首,真正的阻塞者可能已经 idle in transaction。排障要先还原阻塞链和事务年龄。 核心判断 用 pg_blocking_pids 获取阻塞者,再关联 pg_stat_activity。 同时观察 wait_event、xact_start 和应用名,判断锁等待来源。 先与业务方确认事务副作用,再决定取消语句或终止会话。 最小示例 下面保留核心逻辑;业务类型、调用入口和环境配置按项目补齐。 SELECT blocked.pid AS blocked_pid, blocker.pid AS blocking_pid, now() - blocker.xact_start AS blocking_xact_age, blocked.wait_event_type, blocked.wait_event, blocked.query AS blocked_query, blocker.query AS blocking_query FROM pg_stat_activity AS blocked CROSS JOIN LATERAL unnest(pg_blocking_pids(blocked.pid)) AS p(pid) JOIN pg_stat_activity AS blocker ON blocker.pid = p.pid ORDER BY blocking_xact_age DESC NULLS LAST; 边界与误区 仅按 locktype 连接 pg_locks 会错误关联不同锁对象。示例使用官方阻塞关系函数;高频查询也有开销,诊断权限与采样频率应受控。 验证方式 建立一个长事务持锁,再让第二个连接等待,核对阻塞 PID 与 SQL。确认取消当前语句和结束整个会话的风险不同,不自动执行终止命令。 小结 监控阻塞者、被阻塞者、事务年龄和 SQL,区分长事务、DDL 与业务冲突。

2026年9月29日 · 1 分钟 · BvBeJ