You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle包死锁排查请求:定位定时批处理失败的锁定对象

这种生产环境下频繁触发的死锁问题真的让人头大,尤其是还影响到定时批处理的稳定性。我给你几个在生产环境安全可行的排查步骤,帮你精准定位到被其他进程锁定的具体对象:

1. 立刻抓取死锁发生时的实时锁信息

Oracle会自动把死锁记录到alert日志和跟踪文件,但直接看这些文件效率不高。建议在死锁发生后马上执行下面的查询,拿到最直观的锁关联数据:

  • 查询当前所有锁等待的会话,同时关联锁定的对象:
SELECT s.sid, s.serial#, s.username, s.program,
       l.type, l.id1, l.id2, l.lmode, l.request,
       o.object_name, o.object_type
FROM v$lock l
JOIN v$session s ON l.sid = s.sid
LEFT JOIN dba_objects o ON l.id1 = o.object_id
WHERE l.request > 0 -- 只筛选正在等待锁的会话
OR (l.lmode IN (6,7) AND l.id1 IN (SELECT id1 FROM v$lock WHERE request>0)); -- 同时找出持有排他/共享锁的阻塞会话

这里要重点关注:*l.lmode=6*代表排他锁(X锁),是最容易引发死锁的锁类型;*l.lmode=7*是共享锁(S锁);通过dba_objects关联就能直接拿到被锁定的表或对象名称。

  • 查看最近发生的死锁记录(11g及以上版本可用):
SELECT * FROM v$deadlock;

如果是老版本Oracle,可以通过AWR视图查询死锁时间范围内的会话:

SELECT ash.session_id, ash.session_serial#, ash.sql_id, ash.blocking_session,
       o.object_name, o.object_type
FROM dba_hist_active_sess_history ash
LEFT JOIN dba_objects o ON ash.current_obj# = o.object_id
WHERE ash.event = 'enq: TX - row lock contention' -- 死锁最常见的等待事件
AND ash.sample_time BETWEEN SYSDATE - 1/24 AND SYSDATE; -- 查询最近1小时的记录
2. 先定位你的批处理会话

因为你的批处理是每10分钟定时触发的,先找到它的会话标识会让排查更精准:

SELECT sid, serial#, username, program, sql_id
FROM v$session
WHERE program LIKE '%你的批处理程序标识%' -- 替换成实际的程序名(比如Job名称)
OR username = '批处理使用的数据库用户'; -- 如果知道用户名可以直接筛选

拿到批处理会话的sid后,回到第一步的锁查询里,就能快速找到它被哪个会话阻塞,以及对应的锁定对象。

3. 分析锁定对象的访问模式

当你拿到具体的锁定对象后,需要进一步分析它的使用情况:

  • 检查这个对象是否被其他定时任务、业务应用频繁读写?比如有没有其他批量更新/删除任务和你的批处理时间重叠?
  • 查看你的批处理SQL是否有优化空间?比如批量操作时有没有走索引?如果是行级锁冲突,大概率是批量操作扫描到的行被其他会话持有锁。
  • 用AWR视图查看对象的锁历史(需要开启AWR):
SELECT lock_type, mode_held, mode_requested, object_name,
       sample_time, session_id, blocking_session
FROM dba_hist_lock l
JOIN dba_objects o ON l.object_id = o.object_id
WHERE o.object_name = '锁定的对象名' -- 替换成实际对象名称
ORDER BY sample_time DESC;
4. 生产环境排查的注意事项
  • 绝对不要随便在生产环境执行ALTER SYSTEM KILL SESSION,除非你确认阻塞会话是无害的,或者已经获得运维团队的许可。
  • 尽量在死锁发生的高峰期(比如批处理触发后的3-5分钟内)执行查询,这样拿到的信息最准确。
  • 如果你的批处理是用DBMS_SCHEDULER创建的,可以查看它的运行日志获取更多上下文:
SELECT log_id, log_date, status, error#, additional_info
FROM dba_scheduler_job_run_details
WHERE job_name = '你的批处理Job名称'
ORDER BY log_date DESC;

内容的提问来源于stack exchange,提问作者Nandy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:30:16