Oracle位图索引引发的阻塞与死锁
转载自:http://blog.itpub.net/12330444/viewspace-619631/ 前面我介绍了itl引发的阻塞与死锁,这里有必要再介绍一下位图索引引发的阻塞与死锁,因为这个也是不同于普通死锁的一种死锁方式,在有位图索引存在的表上面,其实很容易就引发阻塞与死锁。这个阻塞不是发生在表上面,而是发生在索引上。因为位图索引锁定的范围远远比普通的b-tree索引锁定的范围大。 假定,一个表,上面有标志字段(flags),分别是(0、1),而我们在这个flag字段上创建了一个位图索引,那么,现在我们执行如下的语句: Piner@10gR2>update test set flags = 1 where id = 1;
假定id=1的的值原来是0,现在要更新成1,那么,这个语句在位图索引中,将锁住id=1那个记录所在的整个索引块中的flag=0与1的值,如果这个索引块中有很多记录,这个阻塞将是很严重的。另外注意,如果操作的dml不涉及到索引,则是不会被阻塞的。所以,在oltp环境中,如果一个表更新比较频繁,千万不要使用位图索引,如果数据仓库环境中,使用了位图索引,也最好在加载数据的时候将其删除,等数据加载完成以后重新创建。 我们看一个具体的例子 Piner@10gR2>select * from test;
ID FLAG
---------- ----------
1 1
2 1
3 1
4 1
5 1
6 0
7 0
8 0
9 0
10 0
10 rows selected.
我们在上面创建一个位图索引 Piner@10gR2>create bitmap index ind_test on test(flag);
Index created.
然后更新其中的一条记录,仅仅是一条记录 Piner@10gR2>update test set flag = 0 where id=1;
1 row updated.
这个时候,其实整个位图都被锁定了(因为这些记录都在一个索引块中),我们看如下的例子,在另外的会话中,执行如下的语句可以发现: Piner@10gR2>update test set flag = flag where id=6;
1 row updated.
Piner@10gR2>update test set flag = 1 where id=6; --blocked
可以发现第二个语句被阻塞 Piner@10gR2>update test set flag = flag where id=2;
1 row updated.
Piner@10gR2>update test set flag = 0 where id=2; --blocked
同样被阻塞 select EVENT from v$session_wait where sid=153 EVENT ----------------------------- enq: TX - row lock contention
理解了阻塞的原因,那么我们应当就很好理解位图死锁的原因了,数据行死锁差不多,2个进程互相锁住了资源,不同的是,行死锁抢的是同一样的数据,如同一行数据,位图索引死锁抢的是位图值,可以是不同的行。 接上面的表数据,我们模拟一个死锁,在会话1中执行如下命令 Piner@10gR2>update test set flag = 2 where id=1;
1 row updated.
以上命令一旦发出,位图索引中锁住了所有flag=1(原值)以及flag=2(新值)的记录。 Piner@10gR2>update test set flag = 3 where id=6;
1 row updated.
这个命令锁住了所有flag=0(原值)以及flag=3(新值)的记录。 Piner@10gR2>update test set flag = 2 where id=7; --blocked
结果是阻塞了,会话1等待会话2释放位图索引的锁定资源。 Piner@10gR2>update test set flag = 3 where id=2; --blocked
虽然该记录与以上任何记录都不一样,也被阻塞了,等待会话1释放资源,到这里,死锁就形成了,马上可以看到,报了一个错在会话1上: Piner@10gR2>update test set flag = 2 where id=7;
update test set flag = 2 where id=7
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
我们看跟踪文件,发现这里锁定的是索引,因为object_id=13009的对象就是是位图索引
第2楼 logzgh 于2007-05-23 16:21:55 Says: 第3楼 piner 于2007-05-23 19:33:04 Says: 第4楼 piner 于2007-05-23 20:16:03 Says: 第5楼 piner 于2007-05-23 20:55:44 Says: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |