Bitmap index引发的死锁

转载自:http://blog.itpub.net/193161/viewspace-50292/?utm_source=jiancool


对于bitmap index,我们知道,同一个值会利用一个位图来进行索引。假如有如下测试表:

NING@ning>select* from test;
ID NAME
---------- --------------------
1 a
1 b
1 c
2 a
2 b
2 c

那么在ID列上建bitmap index的话,所有ID=1的会放到一个位图中,所有ID=2的是另外一个位图,而在执行DML操作的时候,锁定的将是整个位图中的所有行,而不仅仅是DML涉及到的行。由于锁定的粒度变粗,bitmap index更容易导致死锁的发生。

下面我们利用上面的test作为例子,来演示一下bitmap index导致的deadlock:

1.建立bitmap index

NING@ning>create bitmap index ix_test on test(id);
Index created.

2.在session 1执行

NING@ning>update test set id=3 where id=1 and name='a';
1 row updated.

此时所有id=1的行都被锁定

3.在session 2执行

NING@ning>update test set id=4 where id=2 and name='a';
1 row updated.

此时所有id=2的行都被锁定

4.在session 1执行

NING@ning>update test set id=4 where id=2 and name='b';

此时会话被阻塞

5.在session 2执行

NING@ning>update test set id=3 where id=1 and name='b';

此时会话被阻塞

6.再回到session 1,发现系统检测到了死锁的发生

NING@ning>update test set id=4 where id=2 and name='b';
update test set id=4 where id=2 and name='b'
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource

相关trace文件中的记录:

* SESSION ID:(138.5621) 2007-03-01 10:58:00.187 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
TX-00040001-000000ea 18 138 X 20 134 S TX-0006002d-00000131 20 134 X
18 138 S session 138: DID 0001-0012-00000015 session 134: DID
0001-0014-00000798 session 134: DID 0001-0014-00000798 session 138:
DID 0001-0012-00000015 Rows waited on: Session 134: obj - rowid =
00003199 - AAADGZAAAAAAAAAAAA (dictionary objn - 12697, file - 0,
block - 0, slot - 0) Session 138: obj - rowid = 00003199 -
AAADGZAAAAAAAAAAAA (dictionary objn - 12697, file - 0, block - 0, slot
- 0) Information on the OTHER waiting sessions: Session 134: pid=20 serial=9803 audsid=30524 user: 27/NING O/S info: user:
BEPDG00726-XPAdministrator, term: BEPDG00726-XP, ospid: 2088:4080,
machine: GDCBEPDG00726-XP program: sqlplus.exe application name:
SQL*Plus, hash value=3669949024 Current SQL Statement: update test set
id=4 where id=1 and name=’b’ End of information on OTHER waiting
sessions. Current SQL statement for this session: update test set id=3
where id=2 and name=’b’

死锁发生的根本原因是对于资源的排他锁定顺序不一致。上面的试验中,session1对于bitmap index中的2个位图是先锁定ID=1的位图,然后请求ID=2的位图,而在此之前ID=2的位图已经被session2锁定。

session2则先锁定ID=2的位图,然后请求ID=2的位图,而此前ID=1的位图已经被session1锁定。于是,session1等待session2释放ID=2的位图上的锁,session2等待session1释放ID=1的位图上的锁,死锁就发生了。

而如果我们创建的是普通的B*Tree index,重复上面的试验则不会出现任何的阻塞和死锁,这是因为锁定的只是DML操作涉及到的行,而不是所有ID相同的行。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值