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文件中的记录:
死锁发生的根本原因是对于资源的排他锁定顺序不一致。上面的试验中,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相同的行。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |