Oracle 19c死锁分析与解除
·
一、实时死锁检测
1. 自动检测机制
Oracle每3秒自动检测死锁,会生成以下信息:
- 自动处理:选择代价最小的事务进行回滚
- 报错日志:ORA-00060错误写入alert.log
- 跟踪文件:生成包含死锁详细信息的trace文件
2. 查看实时死锁信息
-- 查看当前被回滚的会话
SELECT s.sid, s.serial#, s.username, s.program, s.sql_id
FROM v$session s
JOIN v$transaction t ON s.saddr = t.ses_addr
WHERE t.status = 'DEAD';
二、死锁日志分析
1. 定位alert.log
-- 查找alert.log路径
SELECT value FROM v$diag_info WHERE name = 'Diag Trace';
在对应目录下使用命令:
tail -500 alert_$ORACLE_SID.log | grep "ORA-00060"
2. 解析跟踪文件
找到包含以下标识的跟踪文件:
*** 2025-02-11T11:44:00.123456
*** SESSION ID:(25.12345) 2025-02-11T11:44:00.123456
*** CLIENT ID:(APPSERVER_USER)
*** SERVICE NAME:(SYS$USERS)
*** MODULE NAME:(JDBC Thin Client)
*** ACTION NAME:(Transaction Commit)
DEADLOCK DETECTED ( ORA-00060 )
三、手动分析死锁链
1. 查询被阻塞会话
SELECT
l1.sid || ',' || s1.serial# blocker,
l2.sid || ',' || s2.serial# waiter,
o.owner || '.' || o.object_name locked_object,
l1.type lock_type,
decode(l1.lmode,1,'NULL',2,'RS',3,'RX',4,'S',5,'SRX',6,'X','NONE') mode_held,
decode(l2.request,1,'NULL',2,'RS',3,'RX',4,'S',5,'SRX',6,'X','NONE') mode_requested
FROM v$lock l1
JOIN v$lock l2 ON l1.id1 = l2.id1 AND l1.id2 = l2.id2
JOIN v$session s1 ON l1.sid = s1.sid
JOIN v$session s2 ON l2.sid = s2.sid
JOIN dba_objects o ON l1.id1 = o.object_id
WHERE l1.block = 1 AND l2.request > 0;
2. 生成死锁图(需诊断包)
-- 生成死锁报告
SELECT dbms_deadlock.report_deadlock() FROM dual;
四、解除死锁操作
1. 强制终止会话
-- 找到阻塞会话
SELECT sid, serial#, status, sql_id
FROM v$session
WHERE sid IN (SELECT sid FROM v$lock WHERE block > 0);
-- 终止会话(立即终止)
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
2. 级联终止(针对分布式死锁)
BEGIN
DBMS_SYSTEM.KILL_SESSION_DELAYED(
sid => 25,
serial => 54321,
delay_seconds => 0);
END;
五、死锁预防策略
1. 事务优化原则
- 访问顺序:统一对多个表的DML操作顺序
- 批量提交:减少单事务锁持有时间
- 索引优化:确保通过索引访问数据
-- 检查缺失索引
SELECT * FROM v$sql_plan
WHERE operation = 'TABLE ACCESS'
AND options = 'FULL'
AND object_owner = 'SCOTT';
2. 锁超时设置
-- 设置事务级锁等待超时(单位:秒)
ALTER SESSION SET ddl_lock_timeout = 30;
六、高级诊断工具
1. 使用AWR分析历史死锁
-- 查询历史死锁事件
SELECT snap_id, instance_number, event, total_waits
FROM dba_hist_system_event
WHERE event_name = 'enq: TX - row lock contention'
ORDER BY snap_id DESC;
2. SQL Monitor分析
-- 查看导致死锁的SQL执行详情
SELECT dbms_sqltune.report_sql_monitor(
sql_id => 'g54fvx7r2kz3b',
type => 'TEXT')
FROM dual;
七、典型死锁场景解决方案
场景1:主键/唯一索引冲突
现象:并发插入相同唯一值
方案:
-- 使用SEQUENCE缓存优化
ALTER SEQUENCE scott.emp_seq CACHE 1000;
场景2:外键未索引
现象:子表DML操作阻塞父表更新
方案:
-- 为外键字段添加索引
CREATE INDEX scott.dept_fk_idx ON emp(deptno);
操作注意事项
- 生产环境终止会话前 必须确认会话的业务影响
- 跟踪文件分析 需关注
row_wait_obj#和row_wait_file#定位具体数据块 - 定期检查 使用
DBMS_LOCK.REQUEST检测潜在锁冲突 - 应用层优化 使用SELECT FOR UPDATE NOWAIT减少锁等待
通过以上方法,90%以上的Oracle死锁问题可在10分钟内定位并解决。对于复杂分布式死锁,建议启用10046跟踪进行深度分析。
更多推荐


所有评论(0)