定位数据库中因锁资源占用导致的"阻塞者"与"等待者"会话,是排查锁等待性能问题的核心语句。
一、SQL脚本
sql
--检查锁阻塞
SELECT DECODE(REQUEST, 0, '阻塞者:', '等待者:') || SID AS 会话标识,
ID1 AS 锁资源标识1,
ID2 AS 锁资源标识2,
LMODE AS 持有锁模式,
REQUEST AS 请求锁模式,
TYPE AS 锁类型
FROM V$LOCK
WHERE (ID1, ID2, TYPE) IN (SELECT ID1, ID2, TYPE FROM V$LOCK WHERE REQUEST > 0) -- 筛选存在锁请求的资源
ORDER BY ID1, REQUEST;
二、脚本说明
该脚本用于识别数据库中的锁依赖关系:
- 标记"阻塞者":持有锁资源、导致其他会话等待的会话;
- 标记"等待者":因锁资源被占用而处于等待状态的会话;
- 定位锁资源:通过
ID1/ID2/TYPE确定具体被争夺的锁资源。
| 字段 | 含义 | 巡检关注点 |
|---|---|---|
| 会话标识 | 会话ID,前缀标注"阻塞者:"/"等待者:" | 直接区分阻塞方与被阻塞方 |
| 锁资源标识1 | 锁对应的核心资源标识(如表ID、行ID) | 相同的锁资源标识1+2+类型表示同一锁资源 |
| 锁资源标识2 | 锁资源的子标识 | 配合前两个字段定位具体锁对象 |
| 持有锁模式 | 会话当前持有的锁模式(0=无锁,1=共享锁,6=排他锁等) | 阻塞者的该值为非0(持有锁) |
| 请求锁模式 | 会话请求的锁模式(0=无请求,非0=请求对应锁) | 等待者的该值>0(正在请求锁) |
| 锁类型 | 锁的类型(如TM=表锁,TX=事务锁) | 常见阻塞类型为TX(事务锁)或TM(表锁) |
三、注意事项
1、如何识别锁阻塞问题
-
区分阻塞关系:
- 前缀为"阻塞者:"的会话,是持有锁的"源头";
- 前缀为"等待者:"的会话,是被阻塞的会话;
- 同一组
锁资源标识1+2+类型的记录,对应同一锁资源的阻塞链。
-
判断严重程度:
- 若"等待者"数量多,说明该锁资源的阻塞情况已影响多个业务会话;
- 若锁类型为
TX(事务锁),通常是长事务未提交导致的阻塞,需优先处理。
2、阻塞问题的处理建议
-
定位阻塞SQL :
通过阻塞者的会话ID(SID)查询其执行的SQL,优化该SQL以缩短事务时间:
sqlSELECT SQL_TEXT FROM V$SQL WHERE SQL_ID = (SELECT SQL_ID FROM V$SESSION WHERE SID = 阻塞者SID); -
终止阻塞会话 :
先查询阻塞者会话的
SERIAL#,再终止会话(需谨慎,避免影响正常业务):sql-- 第一步:查询阻塞者的SERIAL# SELECT SERIAL# FROM V$SESSION WHERE SID = 阻塞者SID; -- 第二步:终止会话 ALTER SYSTEM KILL SESSION '阻塞者SID, 对应的SERIAL#';