Oracle支持多个进程同时对同一个资源进行访问与操作,这很容易让人觉得这样做的结果是资源不同步,但Oracle又满足资源的一致性,如何做到的呢?Oracle就是利用latch和lock来保护资源的。
latch国内被翻译为闩锁,但也有地方被叫为锁存器;而lock,常被说成锁,而很多人常喜欢把Enqueue locks(队列)认为是lock,这也不无错误。
好,引用“高级OWI与Oracle性能调整”里latch与lock对照表:
分类latchlock
目的一个目的:对于内存结构的排他访问为目的(access)
(Oracle 9i开始,cache buffers chains latch在只读时可共享)两个目的:锁模式如果可以互换,允许多个进程共享相同资源:锁模式如果不能互换,允许对资源排他访问
适用范围只适用于SGA内部数据结构,临时保管内存对象,通过单
一操作,控制对内存结构的访问,不是事务单位保护表、数据块、状态对象(state object)等对象,控制数据库的
数据或元数据的访问,事务单位
获取方式可以有两种模式请求:willing-to-wait或no-wait可以通过6种模式请求:null、row share、row exclusive、share、
share row exclusive、exclusive
范围信息存于SGA内部,只能在本地实例上看,latch按实例级
工作信息存于数据库内部,所有实例上课看其他信息,锁数据库级
上工作
复杂度使用单纯命令实现,一般是test-and-set,compare-and-swap或单纯的CPU命令,容易实现使用了包含上下文交换(context switch)的一连串命令语来实现,
实现复杂
持续时间持续时间很短(毫秒单位)持续一定时间(事务执行时间)
队列(queue)进程在获取latch失败后,进入睡眠(sleep)状态时,该请求
不是以队列管理,不按请求顺序提供服务(利用latch wait
list,以队列方式使用的锁存器除外)进程在获取锁失败后,该相应请求是以队列管理的,按请求顺序提供服务(NOWAIT模式除外)
死锁
(deadlock)latch不发生死锁锁使用了队列方式,所以发生死锁的可能性较大,每当发生死锁时,就会创建trace文件
latch为轻量级锁,之所以说成轻量,是因为它速度快、锁实现方法简单。
latch保护的资源是SGA,如果想搜索或修改SGA特定区域的进程,必须获得保护相应区域的latch,并通过这些特定的latch,保护特定资源。
latch基本上使用排他模式(Exclusive),而也有特定的latch使用共享模式,比如cache buffers chains latch在读取工作时使用share模式。
那下面介绍下几个重要的latch:
•cache buffers chains : db cache上搜索特定块的进程时需要获得的latch,对应的等待事件为latch:cache buffers chains
•cache buffers lru chain : db cache上搜索free buffer和dirty buffer进程时需要获得的latch,对应的等待事件为latch:cache buffers lru chain
•shared pool : 共享池的堆区域上预分配到chunk需要获得的latch,对应的等待事件为latch:shared pool
•library cache : 库告诉缓冲区上搜索进程时需要获得的latch,对应的等待事件为latch:library cache
sys@MAA> select name from v$latch where name like ‘%enqueue%’;
NAME
----------------------------------------------------------------------------------------------------enqueues
enqueue hash chains
instance enqueue
enqueue freelist latch
ges enqueue table freelist
message enqueue sync latch
enqueue sob latch
7 rows selected.
通过上面的查询了解到,Enqueue锁也是通过latch受到保护。
Enqueue锁是用Enqueue结构来管理的锁,而Enqueue的结构也存储在SGA区域。我们可以查看vevent_name来了解当前库中都存在什么Enqueue锁。
Enqueue锁所保护的资源定义为,其中锁的名称和资源名称相同,比如熟知的TX锁保护Transaction资源,TM锁保护Table资源,引申别的锁比如US锁保护Undo Segment资源。而标识符中ID1和ID2根据资源类型的不同所代表的含义不同,这里有这种规则:
TM锁: ID1 = Object ID
TX锁:ID1 – USN<<16 | SLOT , ID2 = Sequence
US锁:ID1 – USN
若Enqueue锁引起等待事件,可以通过vlock中的type、ID1、ID2准确地观察哪些资源发生了锁争用。这时候我们也可以通过vsession_wait中的P1、P2、P3获得相同信息,P1=name|mode,P2=ID1,P3=ID2,而P1=name|mode转换为可阅读形式:
select chr(bitand(P1,-16777216)/(16777215) || chr(bitand(p1, 16711680)/65535) "Lock",bitand(p1,65535)) "Mode"from dual;
或者可以直接使用如下SQL:SELECT CHR(bitand(p1,-16777216)/16777215)||
CHR(bitand(p1, 16711680)/65535) "Lock",
TO_CHAR( bitand(p1,65535)) "Mode"
FROM vsession_wait
WHERE event = ‘enqueue’/
Oracle 10g开始,对所有Enqueue资源类型分别定义等待事件,以enq: AA – BBBB事件,比如:enq: TX – row lock contention、enq: TX – contention等,而Oracle定义的等待事件非常多
sys@MAA> select count(*) from vevent_name where name like 'enq%';
COUNT(*)---------- 304
下面再看一下latch和enqueue相关的常用视图:
LATCH相关:
VLATCHNAME displays information about decoded latch names for the latches shown in VLATCH.TherowsofVLATCH. The rows of VLATCH.TherowsofVLATCHNAME have a one-to-one correspondence to the rows of VLATCH.VLATCH.
VLATCH.VLATCH displays aggregate latch statistics for both parent and child latches, grouped by latch name.
VLATCHPARENTdisplaysstatisticsaboutparentlatches.ThecolumnsforVLATCH_PARENT displays statistics about parent latches. The columns for VLATCHPARENTdisplaysstatisticsaboutparentlatches.ThecolumnsforVLATCH_PARENT are the same as those for VLATCH.VLATCH.
VLATCH.VLATCH_CHILDREN displays statistics about child latches. This view includes all columns of VLATCH plus the CHILD# column. Note that child latches have the same parent if their LATCH# columns match each other.
ENQUEUE相关:
VLOCK lists the locks currently held by the Oracle Database and outstanding requests for a lock or latch.
VENQUEUELOCKdisplaysalllocksownedbyenqueuestateobjects.ThecolumnsinthisviewareidenticaltothecolumnsinVENQUEUE_LOCK displays all locks owned by enqueue state objects. The columns in this view are identical to the columns in VENQUEUELOCKdisplaysalllocksownedbyenqueuestateobjects.ThecolumnsinthisviewareidenticaltothecolumnsinVLOCK.
VLOCKED_OBJECT lists all locks acquired by every transaction on the system. It shows which sessions are holding DML locks (that is, TM-type enqueues) on what objects and in what mode.
DBA_WAITERS shows all the sessions that are waiting for a lock. In an Oracle RAC environment, this only applies if the waiter is on the same instance.
另外根据资源类型不同,我们可能还需要观察DBA_OBJECTS、DBA_TABLESPACES、VSESSION、VSESSION_EVENT、VTRANSACTION、VSQL、VUNDOSTAT等视图。