客户反馈最近系统经常锁表,想要找到导致锁表的语句,但是数据库中查不到阻塞会话的当前SQL,根本原因在于锁由事务(Transaction)持有而非SQL语句持有,加锁的SQL通常早已执行结束,而事务却因未提交或回滚而持续打开,导致会话处于空闲状态,因此动态性能视图中无法捕获到正在执行的SQL。最后通过oradebug工具来查找可能导致阻塞的SQL。
oradebug是Oracle数据库专供高级管理员使用的内部诊断"手术刀",核心价值在于通过生成各类转储(如系统状态和Hang分析)来精准定位数据库挂起、崩溃或慢SQL的根源,并能探查甚至修改内存结构;但它属于高风险且无官方文档详细承诺的调试工具,必须持有SYSDBA权限,强烈建议仅在Oracle技术支持指导下使用,否则操作不当极易导致实例宕机。
1、查找阻塞会话信息
sql
SELECT
blocking_session AS blocker_sid,
sid AS blocked_sid,
sql_id,
event AS waiting_event
FROM
v$session
WHERE
blocking_session IS NOT NULL;
BLOCKER_SID BLOCKED_SID SQL_ID WAITING_EVENT
----------- ----------- --------------------------------------- ------------------------------------------------------------
77 69 bc8kzrzxdcvkh enq: TX - row lock contention
2、通过SID查询ORADEBUG需要的参数
-- 将 77 替换为阻塞源会话的 SID
sql
SELECT
s.sid,
s.serial#,
s.status,
p.pid AS orapid, -- 这是 ORADEBUG SETORAPID 需要的参数
p.spid AS ospid
FROM v$session s, v$process p
WHERE s.paddr = p.addr
AND s.sid = 77;
SID SERIAL# STATUS ORAPID OSPID
---------- ---------- ------------- ---------- -----------
77 33 INACTIVE 53 48392
3、对阻塞源会话和被阻塞会话分别生成trc文件
sql
ORADEBUG SETORAPID <SID> -- SID替换为上一步查询出来的ORAPID
SYS@orcl1> ORADEBUG SETORAPID 53 -- 53
Oracle pid: 53, Unix process pid: 48392, image: oracle@rac1
SYS@orcl1> ORADEBUG DUMP SYSTEMSTATE 10
Statement processed.
SYS@orcl1> SYS@orcl1> ORADEBUG TRACEFILE_NAME;
/u01/app/oracle/diag/rdbms/orcl/orcl1/trace/orcl1_ora_48392.trc
在生成的trc文件中搜索被锁的表名,主要找DML语句。