您的位置:首页 > 数据库 > Oracle

oracle死锁原因分析

2010-12-30 17:06 337 查看
今天遇到死锁问题,找到比较好的文章,备忘于此

转贴自:http://publishblog.blogchina.com/blog/tb.b?diaryID=5788685

NB项目组并发测试频频出现死锁,上周五我打开ora20数据库的alert_ora20.log,搜索ORA-000060,并找到如下内容:
Fri Oct 20 17:21:02 2006
ORA-000060: Deadlock detected. More info in file e:/oracle9i/admin/ora20/udump/ora20_ora_2188.trc.

我继续打开后台跟踪文件,C:/lqy/ora20_ora_2188.trc,发现如下内容:
DEADLOCK DETECTED
Current SQL statement for this session:
insert into PT_SCHE_DETAIL (itemName, itemDesc, compID, itemType, itemTempID,parentID,depend, createBy, createDate, lastUpdateBy, lastUpdateDate,OID,status, lockBy, lockDate,vTemporaryBegDate, vTemporaryEndDate,itemLevel,itemColor, itemSeq, vS02, vS03, vS04, vS05,vS06, vS07, vS08, vS09, vS10, vS11, vS12, vS13, vS14, vS15,vS16, vS17, vS18, vS19, vS20, vS21, vS22, vS23, vS24, vS25, vS26, vS27, vS28, vS29, vS30, vS31, vS32, vS33, vS34, vS35,vS36, vS37, vS38, vS39, vS40,vS41, vS42, vS43, vS44, vS45, vS46, vS47, vS48, vS49, vS50,vS51, vS52, vS53, vS54, vS55, vN01, vN02, vN03, vN04, vN05, vN06, vN07, vN08, vN09, vN10, vN11, vN12, vN13, vN14, vN15, vD01, vD02, vD03, vD04, vD05, vD06, vD07, vD08, vD09, vD10,viewByAll,dependUI,milestone,itemFlag,attachFlag,disscussionFlag,ruleFlag,plannedScheDueDate,itemDisplayName, removeFlag, docID, itemID) values(:1,:2,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17,:18,:19,:20,:21, :22,:23,:24,:25,:26,:27,:28,:29,:30,:31,:32,:33,:34,:35,:36,:37,:38,:39,:40,:41, :42,:43,:44,:45,:46,:47,:48,:49,:50,:51, :52,:53,:54,:55,:56,:57,:58,:59,:60,:61,:62,:63,:64,:65,:66,:67,:68,:69,:70,:71,:72,:73,:74,:75,:76,:77,:78,:79,:80,:81, :82,:83,:84,:85,:86,:87,:88 ,:89,:90,:91,:92,:93,:94,:95,:96,:97,:98,:99,:100,:101,:102,:103,:104,:105,:106,:107,:108,:109,:110,:111)
The following deadlock is not an ORACLE error. It is a
deadlock due to user error in the design of an application
or from issuing incorrect ad-hoc SQL. The following
information may aid in determining the deadlock:
Deadlock graph:
---------Blocker(s)-------- ---------Waiter(s)---------
Resource Name process session holds waits process session holds waits
TX-000a002b-00009dff 29 20 X 20 37 S
TX-00040025-00009c85 20 37 X 29 20 S
这是一个死锁症状,两个不同的SESSION都等待共享锁,但是它等待的资源又互相被对方以排外锁hold,x和s锁没办法共存,两个session都没办法运行到下一步,所以deadlock产生了,在Oracle中在行级从来也不加共享锁。这里的共享锁只是表象,它通常发生在以下条件下:
(1)实体完成性和参照完整性,如果后插入的数据取决于之前的数据提交还是回滚(注意在两个Session中),那么后插入数据的session会请求行级共享锁
(2)如果从表外键上未加索引,那么删除主表记录会在从表上加表级共享锁
(3)如果表的字段上面建了bitmap索引,两个Session同时更新这个字段,会锁住这个个位图块,后更新的session要申请行级共享锁
(4)如果数据库中ITL (interested transaction list) 不足的话,那么最后的session申请行级共享锁
经过查看各种资料及测试,最终是锁定在PT_SCHE_DETAIL表的三个Bitmap索引上,因为在trc文件中,deadlock部分总是说当前的sql是insert into pt_sche_detail,想想,插入新记录和更新索引字段都会要锁定位图索引的某一个位图段,前面我们已经说过,位图索引的位图段有可能包含多个ROWID,如果几个SESSION互相都要去锁定同一个位图段,死锁就产生了.经去除这三个位图索引后,再测试并发,并未出现死锁.这三个索引是:
/*
create bitmap index INX_PTSCHEDETAIL_TATUS on PT_SCHE_DETAIL (STATUS, DOCID, VD02)
tablespace APP01
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
create bitmap index T_IDX_DETAIL_ITEMTYPE on PT_SCHE_DETAIL (ITEMTYPE)
tablespace APP01
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
create bitmap index T_IDX_DETAIL_STATUS on PT_SCHE_DETAIL (STATUS)
tablespace APP01
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
*/

之前我们并没有出现过这个问题,但是经过这次并发测试,位图索引的并发性问题还是出现了.这三个索引是在优化TODOTASK SQL语句时加上的:
--TO DO TASK SQL TUNING
--优化的SQL
SELECT COUNT(*)
FROM (SELECT /*+ index_combine(PT_SCHE_DETAIL T_IDX_DETAIL_STATUS T_IDX_DETAIL_ITEMTYPE)*/ PT_SCHE_DETAIL.itemID, PT_SCHE_DETAIL.docID,
PT_SCHE_DETAIL.itemName, PT_SCHE_DETAIL.itemDesc,
PT_SCHE_DETAIL.compID, PT_SCHE_DETAIL.itemType,
PT_SCHE_DETAIL.itemTempID, PT_SCHE_DETAIL.parentID,
PT_SCHE_DETAIL.depend, PT_SCHE_DETAIL.createBy,
PT_SCHE_DETAIL.createDate,PT_SCHE_DETAIL.lastUpdateBy,
PT_SCHE_DETAIL.lastUpdateDate,PT_SCHE_DETAIL.lockBy,
PT_SCHE_DETAIL.lockDate, PT_SCHE_DETAIL.OID,
PT_SCHE_DETAIL.status, PT_SCHE_DETAIL.VS13,
PT_SCHE_DETAIL.VD02,PT_SCHE_DETAIL.itemDisplayName,
PT_SCHE_MASTER.docName, PT_SCHE_MASTER.status AS status2
from PT_SCHE_DETAIL ,PT_SCHE_MASTER,pt_post_role
where PT_SCHE_DETAIL.docID = PT_SCHE_MASTER.docID
and (PT_SCHE_DETAIL.itemid=pt_post_role.taskid
and pt_post_role.roleid = 1004
and pt_post_role.posttype=1)
AND ((PT_SCHE_MASTER.status=1)
AND ((PT_SCHE_DETAIL.status=1) OR (PT_SCHE_DETAIL.status=2)
OR (PT_SCHE_DETAIL.status=3)))
AND (PT_SCHE_DETAIL.itemType != 1)
AND bitand(itemFlag , (1))!= 1 order by PT_SCHE_DETAIL.VD02
ASC nulls first)

--优化方法
--在pt_sche_detail上创建两个位图索引
create bitmap index T_IDX_DETAIL_STATUS on PT_SCHE_DETAIL (STATUS) COMPUTE STATISTICS
tablespace INX02
storage
(
initial 64K
minextents 1
maxextents unlimited
);

create bitmap index T_IDX_DETAIL_ITEMTYPE on PT_SCHE_DETAIL (ITEMTYPE) COMPUTE STATISTICS
tablespace INX02
storage
(
initial 64K
minextents 1
maxextents unlimited
);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: