一、簡介
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的記錄 |
預防死鎖風險 | 分析事務是否訪問相同行但不同順序 |