oracle rac全局死锁必须从alert.log提取did、定位_lmd_*.trc文件、结合v$ges_blocking_enqueue和xid反推sql,跳过任一环节仅见ora-00060。

Oracle RAC全局死锁不是“查不到就重启”的问题,而是必须从alert.log里抓DID、进_LMD_*.trc文件定位事务链、再靠v$ges_blocking_enqueue和XID反推真实SQL——跳过任一环节,就只能看到“ORA-00060”,看不到谁锁了谁、哪两行在争。
从alert日志提取DID和trace路径是唯一入口
全局死锁不会写进_ORA_*.trc,只会在alert.log中留下一行线索,形如:Global Enqueue Services Deadlock detected (DID=11_0_3092). More information in file /u01/app/odaorabase/oracle/diag/rdbms/erpcdb/erpcdb1/trace/erpcdb1_lmd0_89756.trc。这行不是可选信息,是唯一入口:
-
DID=11_0_3092中的三段数字分别代表实例号、节点号、序列号,用于在trace中快速定位死锁段 - 路径里的
erpcdb1_lmd0_89756.trc必须去对应实例的trace目录下找,不能凭名字猜——RAC各节点trace独立存放 - 别在
alert.log里搜ORA-00060:它只记录事件发生,不带上下文;真正结构化信息全在_LMD_*.trc里
在_LMD_*.trc中用DID定位死锁事务段
_LMD_*.trc是LMD进程生成的精简日志,不含绑定值、不展开SQL文本,但包含完整的阻塞关系和XID。打开后搜索DID=11_0_3092,你会看到类似这样的块:
*** 2026-07-28T07:12:44.123456+08:00 DID = 11_0_3092 Resource Name: TX-000a-000003f2-00000001 GRANTING_INST_ID = 1 BLOCKING_INST_ID = 2 XID = 0x000A.01F.000003F2
关键点:
-
Resource Name以TX-开头表示事务锁,US-开头则说明是undo segment争用(事务未提交导致GC读一致性失败) -
GRANTING_INST_ID和BLOCKING_INST_ID告诉你跨实例阻塞方向,必须去对应实例查gv$session -
XID是核心线索:它能关联到v$transaction和归档日志,是还原完整DML语句的唯一ID
用v$ges_blocking_enqueue和XID交叉验证阻塞源头
仅靠trace里的XID还不够,因为_LMD_*.trc不提供SQL文本。得用实时视图确认当前是否还卡着,并锁定会话:
- 执行
SELECT * FROM v$ges_blocking_enqueue WHERE resource_name LIKE 'TX-%',重点关注GRANTING_INST_ID和REQUESTING_INST_ID列,比gv$session.blocking_session更可靠——后者对瞬时GC等待常为空 - 拿到XID后,查
SELECT sid, serial#, sql_id FROM gv$session s, gv$transaction t WHERE s.taddr = t.addr AND t.xidusn||'.'||t.xidslot||'.'||t.xidsqn = '0x000A.01F.000003F2'(注意格式转换) - 再用
SELECT sql_text FROM gv$sql WHERE sql_id = '<sql_id>'</sql_id>看实际语句;若为空,说明SQL已老化出共享池,必须用LOGMINER解析归档日志回溯
别调_lm_dd_interval,先盯enq: TX - row lock contention
很多人一见60秒检测延迟就想改_lm_dd_interval,这是高风险动作:10.2.0.3+版本设为0直接导致实例无法启动,设为30秒以下实测LMD CPU持续超80%。真正该盯的是性能指标:
- 查AWR报告中
enq: TX - row lock contention的平均等待时间,若持续>500ms,说明不是检测慢,而是GC协调本身卡在中间环节(比如私网延迟或心跳异常) - RAC死锁70%以上源于业务层更新顺序不一致:事务A按
id=1→id=2更新,事务B按id=2→id=1更新——数据库层调参治标,统一主键升序更新才能治本 - kill session务必带
@inst_id:例如ALTER SYSTEM KILL SESSION '123,456@2' IMMEDIATE,漏掉@2可能在错误节点执行,白杀
最易被忽略的是:死锁被LMD打破后,被牺牲会话的锁会被释放,但另一端的锁等待仍存在——你看到ORA-00060报错返回,不等于阻塞已解除;必须检查v$locked_object和gv$session确认锁是否真清空,否则应用重试会立刻再次触发死锁。











