Bitmap index引发的死锁

前端之家收集整理的这篇文章主要介绍了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,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相同的行。

猜你在找的Oracle相关文章