PostgreSQL pgrowlocks 扩展详解
一、简介
pgrowlocks 是 PostgreSQL 官方提供的扩展模块,用于查看指定表中每一行当前的行级锁(Row Lock)信息。它非常适用于:
- 并发冲突排查
- 行级锁等待分析
- 死锁前兆探测
- 热点数据行分析
二、安装与启用
1. 安装前提(已包含在 postgresql-contrib 包中):
对于大多数 PostgreSQL 安装环境,pgrowlocks 已预编译,无需手动编译。
2. 启用扩展(数据库级别):
CREATE EXTENSION pgrowlocks;
每个数据库需单独创建一次扩展;
或者
在template1模版数据库中安装扩展,随后新建数据库自带pgrowlocks。
三、功能作用
功能点 | 描述 |
查看行级锁持有者信息 | 包括事务 ID、锁模式、后台 PID 等 |
分析锁冲突或阻塞原因 | 判断是否存在热点行或锁竞争 |
融合pg_stat_activity | 定位哪个语句/事务导致锁住了哪些行 |
多事务共享锁的诊断 | 支持显示多事务共持一行锁的情况 |
四、输出字段详解
执行:
SELECT * FROM pgrowlocks('your_table');
将返回如下字段:
字段名 | 含义说明 |
locked_row | 被加锁行的 ctid(元组标识符,形如 (block, offset)) |
locker | 加锁的事务 ID(XID) |
multi | 是否是多事务锁(即多事务持有此行锁) |
xids | 多事务下所有持锁事务的事务 ID 数组 |
modes | 锁模式(如 'For Update'、'For Share' 等) |
pids | 加锁事务对应的后端进程 PID 数组(可结合 pg_stat_activity 使用) |
- 示例输出
SELECT * FROM pgrowlocks('orders');
可能返回如下内容:
locked_row | locker | multi | xids | modes | pids
------------+--------+-------+--------------+--------------+---------
(0,5) | 123456 | f | {123456} | {For Update} | {2743}
2. 字段详解
字段 | 示例 | 含义 |
locked_row | (0,5) | 被加锁行在表中的物理位置 |
locker | 123456 | 持锁事务的Transaction ID(主事务) |
multi | f | 表示该锁是否由多个事务共享 |
xids | {123456} | 所有持锁事务ID |
modes | {For Update} | 锁的类型 |
pids | {2743} | 加锁事务对应的后台进程号 |
五、典型用法示例
1. 查询表中当前被加锁的所有行:
SELECT * FROM pgrowlocks('orders');
2. 联合 pg_stat_activity 查锁住行的 SQL:
SELECT a.pid, a.query, a.state, r.locked_row, r.modes
FROM pgrowlocks('orders') r
JOIN pg_stat_activity a
ON a.pid = ANY(r.pids);
3. 排查是否存在多事务共享锁
SELECT * FROM pgrowlocks('orders') WHERE multi = true;
六、注意事项
· pgrowlocks 扫描整张表,可能会 引起性能影响,慎用在线业务环境!
· 只支持 Heap 表(普通表),不支持 TOAST、外部表等。
· 仅显示当前存在的锁,不是历史信息。
七、使用建议场景
场景 | 建议操作 |
排查热点行更新冲突 | 查询频繁锁定的ctid |
联合pg_stat_activity定位阻塞 | 找到具体SQL和PID |
多事务竞争插入同一行 | 查看multi=true的记录 |
预防死锁风险 | 分析事务是否访问相同行但不同顺序 |