目前就职海天起点,服务于电力行业,致力于帮助客户解决生产过程中出现的问题,提高生产效率, 爱好书法,周易!愿结交志同道合之士!共同进步! 微信号:sunyunyi_sun
系统发生死锁应该如何正确快速找出原因,这个问题经常困扰DBA,因为死锁一旦发现orale自动清除阻塞者,
所以很难从相关视图中查找有用信息,而大部分DBA不善于分析trace文件内容,因为trace文件很难看懂呀!
其实不然,当我们养成了看trace的习惯你会发现oracle trace 文件很详细而且很容易看懂,oracle各种trace
报告dump文件都是一样的,最近客户遇到了大量的死锁问题导致应用大量报错,我模拟TX 死锁类型,讲解
如何看懂死锁trace文件内容。
这里只测试TX在RAC环境的死锁,至于单实例trace很好看懂,里面详细列出了等待着和阻塞者的信息。另外
其他类型的死锁测试大家可以自己构建,比如典型的位图死锁,ITL死锁,外键无索引死锁。
实验环境:11.2.0.4 RAC LINUX 5.8
1. TX deadlock in Exclusive(X) mode
node2:
create table tbdl (id number,name varchar2(200))
/
insert into tbdl values(1,'a')
/
insert into tbdl values(2,'b')
/
insert into tbdl values(3,'c')
/
commit
/
node2 session1:
select sid from v$mystat where rownum<2;
select s.sid,s.SERIAL#,s.saddr,p.pid,p.spid from v$process p,v$session s
where s.paddr = p.addr
and s.sid=
(select sid from v$mystat where rownum<2)
/
SID SERIAL# SADDR PID SPID
---------- ---------- ---------------- ---------- ------------------------
1146 34903 00000000EFC07780 34 19635
update tbdl set name='sb' where id=2;
node1 session2:
SID SERIAL# SADDR PID SPID
---------- ---------- ---------------- ---------- ------------------------
15 14837 00000000F0D9B7E0 44 29988
update tbdl set name='la' where id=1;
node2:
update tbdl set name='sa' where id=1;
node1:
update tbdl set name='lb' where id=2;
node2:
SQL> update tbdl set name='sa' where id=1;
update tbdl set name='sa' where id=1
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
node1:
waiting
全局事物:
select s.INST_ID,s.sid,p.spid,s.SQL_ID,t.XIDUSN,t.XIDSLOT,t.XIDSQN,t.STATUS
from gv$session s,gv$process p,gv$transaction t
where
s.INST_ID=p.INST_ID
and p.INST_ID=t.INST_ID
and s.PADDR=p.ADDR
and s.TADDR=t.ADDR
/
Inst
id SID SPID SQL_ID XIDUSN XIDSLOT XIDSQN STATUS
---- ----- ------------------------ --------------- ---------- ---------- ---------- ----------
2 1146 19635 f45a3usq403ws 7 31 108110 ACTIVE
1 15 29988 f28tgjwt4s0qm 11 28 110592 ACTIVE
死锁过程:
1:node2 lock ID=2 持有ID=2 TX
2:node1 lock ID=1 持有ID=1 TX
3:node2 req lock ID=1 NODE1持有ID=1 TX,NODE2 等待ID=1 tx
4:node1 req lock ID=2 NODE2持有ID=2 TX,NODE1 等待ID=2 tx
死锁产生,oracle 撤销第三步 node2 req lock ID=1 操作。
我们分析trace文件,因为当业务发生死锁时oracle自动解除死锁,我们只能看到trace文件内容,
所以必须要读懂trace文件
Global Enqueue Services Deadlock detected. More info in file
/u01/app/oracle/diag/rdbms/pmssn/pmssn_2/trace/pmssn_2_lmd0_1230.trc.
trace文件开始打印阻塞者的信息,因为node1第四步最终导致了死锁,
node2是阻塞者,下面就是阻塞者node2的信息。
*** 2017-11-20 08:43:19.185
DUMP LOCAL BLOCKER/HOLDER: block level 5 res [0x7001f][0x1a64e],[TX][ext 0x0,0x0]
注释:
这里首先dump 本地BLOCKER/HOLDER:本地阻塞者,[0x7001f][0x1a64e],[TX] 是节点2的事物xid
以前文章讲过enqueue的结构,eq是由资源和lock队列组成,下面首先是资源信息,后面对应lock信息主要持有者和转换者列表。
----------resource 0xecb1aeb8----------------------资源
resname : [0x7001f][0x1a64e],[TX][ext 0x0,0x0] --资源名,前面就是事物的XID号,对应UNDO段solt和seq
hash mask : x3
Local inst : 2
dir_inst : 2
master_inst : 2
hv idx : 65
hv last r.inc : 2
current inc : 12
hv status : 0
hv master : 1
open options : dd
grant_bits : KJUSERNL KJUSEREX
grant mode : KJUSERNL KJUSERCR KJUSERCW KJUSERPR KJUSERPW KJUSEREX
count : 1 0 0 0 0 1
val_state : KJUSERVS_NOVALUE
valblk : 0x000000000000000000000000a17f0000 .
access_inst : 2
vbreq_state : 0
state : x0
resp : 0xecb1aeb8
On Scan_q? : N
Total accesses: 62
Imm. accesses: 59
Granted_locks : 1
Cvting_locks : 1
value_block: 00 00 00 00 00 00 00 00 00 00 00 00 a1 7f 00 00
GRANTED_Q :持有链表,持有tx锁
lp 0xea2111e8 gl KJUSEREX rp