【转】外键缺少索引引发的死锁

客户的10.2.0.4 RAC for AIX环境频繁出现ORA-60死锁问题,导致应用程序无法顺利执行。


经过一系列的诊断,发现最终问题是由于外键上没有建立索引所致,由于程序在主子表上删除数据,缺少索引导致行级锁升级为表级锁,最终导致大量的锁等待和死锁。

下面通过一个例子简单模拟一下问题:

SQL> create table t_p (id number primary key, name varchar2(30));

Table created.

SQL> create table t_f (fid number, f_name varchar2(30), foreign key (fid) references t_p);

Table created.

SQL> insert into t_p values (1, 'a');

1 row created.

SQL> insert into t_f values (1, 'a');

1 row created.

SQL> insert into t_p values (2, 'b');

1 row created.

SQL> insert into t_f values (2, 'c');

1 row created.

SQL> commit;

Commit complete.

SQL> delete t_f where fid = 2;

1 row deleted.

这时在会话2同样对子表进行删除:

SQL2> delete t_f where fid = 1;

1 row deleted.

回到会话1执行主表的删除:

SQL> delete t_p where id = 2;

会话被锁,回到会话2执行主表的删除:

SQL2> delete t_p where id = 1;

会话同样被锁,这时会话1的语句被回滚,出现ORA-60死锁错误:

delete t_p where id = 2
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource


SQL> rollback;

Rollback complete.

将会话1操作回滚,会话2同样回滚并建立外键列上的索引:


1 row deleted.

SQL2> rollback;

Rollback complete.

SQL2> create index ind_t_f_fid on t_f(fid);

Index created.

重复上面的步骤会话1删除子表记录:

SQL> delete t_f where fid = 2;

1 row deleted.

会话2删除子表记录:

SQL2> delete t_f where fid = 1;

1 row deleted.

会话1删除主表记录:

SQL> delete t_p where id = 2;

1 row deleted.

会话2删除主表记录:

SQL> delete t_p where id = 1;

1 row deleted.

所有的删除操作都可以成功执行,关于两种情况下锁信息的不同这里就不深入分析了,重点就是在外键列上建立索引。

虽然有一些文章提到过,如果满足某些情况,可以不在外键列上建立的索引,但是我的观点一向是,既然创建了外键,就不要在乎再多一个索引,因为一个索引所增加的代价,与缺失这个索引所带来的问题相比,是微不足道的。

参考:
[url]http://yangtingkun.itpub.net/post/468/524858[/url]
[url]http://www.cnblogs.com/angzi/archive/2006/12/09/587612.html[/url]


【补充】Oracle 10g和Oracle 9i trc日志内容的差别

[b]Oracle 10g 10.2.0.3.0:[/b]

DEADLOCK DETECTED ( ORA-00060 )
[Transaction Deadlock]
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
TM-0000dd55-00000000 16 146 SX SSX 17 148 SX SSX
TM-0000dd55-00000000 17 148 SX SSX 16 146 SX SSX
session 146: DID 0001-0010-00000008 session 148: DID 0001-0011-00000006
session 148: DID 0001-0011-00000006 session 146: DID 0001-0010-00000008
Rows waited on:
Session 148: no row
Session 146: no row
Information on the OTHER waiting sessions:
Session 148:
pid=17 serial=39 audsid=540046 user: 54/SCOTT
O/S info: user: SKYHOME\sky, term: SKYHOME, ospid: 3028:7000, machine: WORKGROUP\SKYHOME
program: plsqldev.exe
application name: PL/SQL Developer, hash value=1190136663
action name: Command Window - New, hash value=254318129
Current SQL Statement:

delete t_p where id = 1
End of information on OTHER waiting sessions.
Current SQL statement for this session:
delete t_p where id = 2


[b]Oracle 9i 9.2.0.7.0:[/b]

DEADLOCK DETECTED
Current SQL statement for this session:
delete t_p where id = 2
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
TM-0000260e-00000000 21 51 SX SSX 23 20 SX SSX
TM-0000260e-00000000 23 20 SX SSX 21 51 SX SSX
session 51: DID 0001-0015-0000043D session 20: DID 0001-0017-00000397
session 20: DID 0001-0017-00000397 session 51: DID 0001-0015-0000043D
Rows waited on:
Session 20: no row
Session 51: no row
Information on the OTHER waiting sessions:
Session 20:
pid=23 serial=53179 audsid=197296 user: 87/scott
O/S info: user: sky, term: SKYHOME, ospid: 5540:4984, machine: WORKGROUP\SKYHOME
program: plsqldev.exe
client info: 127.0.0.1
application name: PL/SQL Developer, hash value=1190136663
action name: Command Window - New, hash value=254318129
Current SQL Statement:

delete t_p where id = 1
End of information on OTHER waiting sessions.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值