<让oracle跑得更快-2> 锁和阻塞

2.1 锁和阻塞
首先,注意区别并发(concurrency)和并行(parallel)两个词。 在数据库中,并发的意思是说有超过两个以上的用户对同样的数据做修改(可能包括插入,删除和修改),而 并行的意思是说将一件事情分成很多小的部分,让每一部分同时执行,最后将执行结果汇总成最终结果。 没有并发,就没有锁,锁的产生是因为并发

开发人员经常提到的“锁表”其实就是一个会话被另一个会话阻塞。我们可以从一个视图中看到这些信息:
Select sid, type, id1, id2,lmode, request, block from v$lock where sid in (sessionId1, sessionId2) order by sid;
当不知道锁表相关的会话id时,也可以查询到会话信息,可以参考: http://www.iteye.com/topic/571315

关于锁的详细信息这里不多介绍,只是提几点。
(1)TM锁是个表级共享锁,每个用户都可以以共享的方式(lmode=3, lmode是v$lock的一个字段)持有它,这个锁上面,没有阻塞和等待。其实TM锁更像是一个段级的锁,通常我们叫它表锁,是因为我们把它这个表看做一个段,当某个表有几个段的时候,每个段上都会分别加上TM锁。
TM是一个段级的共享锁,它允许同级别(或更低级别)的锁同时设置,但拒绝高级别的锁定请求(DDL操作需要一个更高级别的排他表级锁)。

(2)很多人一看到 TX锁,就不由自主想到是一个行级排他锁,这样理解有时候会误导,它的真正目的其实只是维护一个事务的完整性, 理解为“事务锁”。在多数情况下,这种事务是更新表的数据,所以给人一种印象,它就是加在数据行上的一个排他锁。它的真正意思是说,这个事务锁会在行级对数据产生影响,比如说阻塞。同样,TM锁也并非是加在表上的一个锁,它会在表的级别上产生影响,比如它不允许其他用户对表做DDL操作。

(3)在oracle里面,并不存在真正意义上的属于某个对象或数据的锁,那需要一个锁管理器,无形中锁管理器自身又产生另一个申请锁的等待,就是等待锁管理器来分配和释放锁。在oracle数据库中,它并不会对某个表上加个锁或某几行加上锁, 锁是以数据块的一个属性存在的。也就是说,每个数据块本身就存储着自己数据块中数据的信息,这个地方叫ITL(Interested Transaction List),凡是在这个数据块上有活动的事务,它的信息就会记录在这里供后续的操作查询,以保证事务的一致性。Oracle不存在锁管理器,申请1000000个锁和申请一个锁的开销是一样的。

2.2 引起阻塞的其他情况
除了由于唯一约束引起的阻塞之外,在生产环境中还经常会遇到下面 两种情况引起的阻塞:
(1) select for update,以排他的方式获得这些需要修改行的数据
还可以参考:[url] http://zoroeye.iteye.com/blog/2173694[/url]
(2) 外键没有创建索引
如果你的系统有主外键引用关系,并且满足以下三个条件中的任一个,那么你应该考虑给外键字段创建索引,否则系统的性能可能会下降甚至阻塞。
1) 主表上有频繁的删除操作
2) 主键上有频繁的修改操作
3) 业务上经常会出现主表和从表做关联查询的情况
第一个和第二个条件操作的时候,主表会在从表上创建一个锁定,以保证主表主键的修改不会导致从表的数据在引用上出现问题,这是一个数据引用完整性的要求。如果主表上经常出现这样的删除或是对主键列进行修改的操作,或者每次操作的记录数很多,都将造成从表长时间被锁定,而影响其他用户的正常操作。比如主表每次删除1000行数据,它就需要扫描从表1000次(如果是全表扫描,性能可想而知),以确定每一行记录的改变都不会造成从表数据在引用上的不完整。
还可以参考: http://zoroeye.iteye.com/blog/2182162

猜你喜欢

转载自zoroeye.iteye.com/blog/2187015