pg_locks视图返回当前正在持有或等待的锁状态快照,每行表示一个backend进程与锁对象(表、行、事务ID等)的关联关系;需联查pg_stat_activity才能获取进程和SQL信息。
pg_locks 视图返回的是什么数据
pg_locks 是 PostgreSQL 内置的系统视图,它不存储锁的历史记录,只反映当前**正在持有或等待中**的锁状态。每一行代表一个锁对象(如表、行、事务ID等)与一个进程(pid)之间的关联关系。注意:它不是“谁锁了谁”的直观映射,而是“某个 backend 持有/等待某类锁”的快照。
如何查出带进程和 SQL 的完整锁信息
单独查 pg_locks 几乎没用,必须关联 pg_stat_activity 才能知道哪个会话在执行什么 SQL。常用组合查询如下:
SELECT l.pid, a.usename, a.application_name, a.client_addr, l.mode, l.granted, l.locktype, l.relation::regclass AS table_name, l.page, l.tuple, a.state, a.query FROM pg_locks l JOIN pg_stat_activity a ON l.pid = a.pid WHERE a.pid pg_backend_pid();
关键点:
-
l.granted = false表示该进程正在等待锁(可能被阻塞) -
l.locktype = 'relation'对应表级锁,'tuple'对应行级锁(需结合page和tuple定位) -
a.state = 'active'或'idle in transaction'的会话更值得关注 - 过滤掉
pg_backend_pid()是为了避免查到当前查询自身的锁(除非你故意要查)
为什么看不到行锁的具体 WHERE 条件
pg_locks 不保存 SQL 的谓词条件,它只记录锁作用的对象(比如第 5 页第 12 行),无法反推出 “WHERE id = 100” 这样的逻辑。如果你看到 locktype = 'tuple',只能确认有行锁存在,但具体锁了哪几行,得结合 query 字段里的 SQL + 表结构 + 当前事务的隔离级别来推理。
常见误区: