pg_stat_activity 一页纸:看哪几列、三条查询定位阻塞
pg_stat_activity 有 22 列,日常真正要看的只有 6 个:pid、usename、application_name、state、wait_event_type、wait_event。其余是审计与排查细节。
1. 列与取值
| 列 | 看什么 |
|---|---|
state | active / idle / idle in transaction / idle in transaction (aborted) / fastpath function call / disabled |
wait_event_type | Lock(等锁)、IO(等 I/O)、LWLock(轻量锁)、Client(等客户端)、IPC、Timeout、Activity;为 NULL 表示正在跑不等待 |
query_start | 这条语句开始的时间,算"跑了多久"用它 |
xact_start | 事务开始时间,算"事务开了多久"用它 |
backend_type | client backend / checkpointer / walwriter 等,查连接时要过滤 |
本机单条连接的真实取值长这样:active | - | - | client backend,即正在执行、没有等待事件。
2. 三条查询
-- 1) 跑了超过 5 分钟的活动查询
SELECT pid, usename, application_name,
now() - query_start AS running,
left(query, 80) AS q
FROM pg_stat_activity
WHERE state = 'active' AND now() - query_start > interval '5 minutes'
ORDER BY running DESC;
-- 2) 阻塞树:谁在等谁
SELECT pid, pg_blocking_pids(pid) AS blockers, state,
now() - query_start AS running, left(query, 60)
FROM pg_stat_activity
WHERE cardinality(pg_blocking_pids(pid)) > 0;
-- 3) idle in transaction 泄漏
SELECT usename, application_name, state, count(*), max(now() - xact_start) AS longest
FROM pg_stat_activity
WHERE state LIKE 'idle in transaction%'
GROUP BY 1,2,3 ORDER BY 5 DESC;
第 2 条里的 pg_blocking_pids() 是核心:它直接给出阻塞者的 pid,不用自己 join 锁视图。
3. 三个判读要点
idle 不可怕,idle in transaction 才可怕。前者是连接空着,后者是事务开着但没干活,它持有快照、阻止 vacuum、可能持锁。超过几十秒的 idle in transaction 基本等于泄漏。
wait_event_type = Lock 说明在等锁,去看第 2 条查询找谁持有。等 I/O(IO)则是另一条路,要考虑存储或 shared_buffers。
state = active 且 wait_event 为 NULL,说明正在消耗 CPU。这时候看 duration 没用,要看执行计划(必要时上 auto_explain)。
小结
pg_stat_activity 能回答三个问题:谁在跑、跑了多久、在等什么。它回答不了"为什么慢"——那需要执行计划、pg_stat_statements 或 eBPF。
日常巡检查第 3 条 SQL(idle in transaction)就够了,它对应的问题最贵:一个泄漏的连接池能把整库拖慢,而监控面板上看不出异常。
数据来源与检索时间
检索时间 2026-11-10。列名与取值来自本机 18.6 的 information_schema 与实测输出。
| 来源 | URL | 对应数据 |
|---|---|---|
| PostgreSQL 18 文档《27.2 统计信息视图》 | https://www.postgresql.org/docs/18/monitoring-stats.html | pg_stat_activity 各列定义、state 与 wait_event_type 的取值含义 |
| PostgreSQL 18 文档《9.27 系统信息函数》 | https://www.postgresql.org/docs/18/functions-info.html | pg_blocking_pids() 的语义(返回直接与间接阻塞者的 pid 数组) |
核验说明
- 列名清单取自本机
information_schema.columns实查(22 列),单条连接的取值也来自实跑。 - 三条查询只在本机空载实例上跑通、语法与返回结构正确;没有构造真实的阻塞场景来验证
pg_blocking_pids()的返回值,这一点依据文档。