ITPub博客

首页 > 数据库 > Oracle > [整理]锁和Latch

[整理]锁和Latch

原创 Oracle 作者:halfgene 时间:2007-08-24 23:19:17 0 删除 编辑
1、Latch和Lock的区别
2、LATCH的产生过程
3、如何查看是否存在latch争用
4、检查latch free是不是主要的wait event
5、DBA需要关注的latch有:
6、锁概述
6、死锁[@more@]

Latch是Oracle提供的轻量级锁资源,他用于快速,短时间的锁定资源,防止多个并发进程同时修改访问某个共享资源,他只工作在内存中,我们可以不大准确的说,内存中资源的锁叫latch,数据库对象(表,索引等)的锁叫Lock。比如数据缓存中的某个块要被读取,我们会获得这个块的latch,这个过程叫做pin,另外一个进程恰好要修改这个块,他也要pin这个块,此时他必须等待,当前一个进程释放latch后才能pin住,然后修改,如果多个进程同时请求的话,他们之间将出现竞争,没有一个入队机制,一旦前面进程释放所定,后面的进程就蜂拥而上,没有先来后到的概念,这个和Lock是有本质区别的,这一切都发生的非常快,因为Latch的特点是快而短暂,当然这个只是大致过程,细节部分在后面讨论

1、Latch和Lock的区别,
a.Latch是对内存数据结构提供互斥访问的一种机制,而Lock是以不同的模式来套取共享资源对象,各个模式间存在着兼容或排斥,从这点看出,Latch的访问,包括查询也是互斥的,任何时候,只能有一个进程能pin住内存的某一块,幸好这个过程是相当的短暂,否则系统性能将没的保障,现在从9I开始,允许多个进程同时查询相同的内存块,但性能并没有想象中的好。
b.Latch只作用于内存中,他只能被当前实例访问,而L ock作用于数据库对象,在RAC体系中实例间允许Lock检测与访问
c.Latch是瞬间的占用,释放,Lock的释放需要等到事务正确的结束,他占用的时间长短由事务大小决定
d.Latch是非入队的,而Lock是入队的
e.Latch不存在死锁,而Lock中存在(死锁在Oracle中是非常少见的)

2、LATCH的产生过程
现在来看看进程获取Latch的详细过程,任何时候,只有一个进程可以访问内存中的某一个块(9I提出的Latch共享我不想考虑),如果进程因为别的进程正占用块而无法获得Latch时,他会对CPU进行一次spin(旋转),时间非常的短暂,spin过后继续获取,不成功仍然spin,直到spin次数到达阀值限制(这个由隐含参数_spin_count指定),此时进程会停止spin,进行短期的休眠,休眠过后会继续刚才的动作,直到获取块上的Latch为止。进程休眠的时间也是存在算法的,他会随着spin次数而递增,以厘秒为单位,如1,1,2,2,4,4,8,8,。。。休眠的阀值限制由隐含参数_max_exponential_sleep控制,默认是2秒,如果当前进程已经占用了别的Latch,则他的休眠时间不会太长(过长会引起别的进程的Latch等待),此时的休眠最大时间有隐含参数_max_sleep_holding_latch决定,默认是4厘秒。这种时间限制的休眠又称为短期等待,另外一种情况是长期等待锁存器(Latch Wait Posting),此时等待进程请求Latch不成功,进入休眠,他会向锁存器等待链表(Latch Wait List)压入一条信号,表示获取Latch的请求,当占用进程释放Latch时会检查Latch Wait List,向请求的进程传递一个信号,激活休眠的进程。Latch Wait List是在SGA区维护的一个进程列表,他也需要Latch来保证其正常运行,默认情况下share pool latch和library cache latch是采用这个机制,如果将隐含参数_latch_wait_posting设置为2,则所有Latch都采用这种等待方式,使用这种方式能够比较精确的唤醒某个等待的进程,但维护Latch Wait List需要系统资源,并且对Latch Wait List上Latch的竞争也可能出现瓶颈。

如果一个进程请求,旋转,休眠Latch用了很长时间,他会通知PMON进程,查看Latch的占用进程是否已经意外终止或死亡,如果是则PMON会清除释放占用的Latch资源。

现在大家可以明白,对Latch获取的流程了,请求-SPIN-休眠-请求-SPIN-休眠。。。占用,这里有人会问为什么要SPIN,为什么不直接休眠等待?这里要明白休眠意味着什么,他意味着暂时的放弃CPU,进行上下文切换(context switch),这样CPU要保存当前进程运行时的一些状态信息,比如堆栈,信号量等数据结构,然后引入后续进程的状态信息,处理完后再切换回原来的进程状态,这个过程如果频繁的发生在一个高事务,高并发进程的处理系统里面,将是个很昂贵的资源消耗,所以他选择了spin,让进程继续占有CPU,运行一些空指令,之后继续请求,继续spin,直到达到_spin_count值,这时会放弃CPU,进行短暂的休眠,再继续刚才的动作,Oracle软件就是这么设计的


系统发生关于Latch的等待是没发避免的,因为这是Oracle的运作机制,当你看到很高的Latch get时并不意味着你的系统需要调整,有时候很高的get值背后只有很短的等待时间,我们调整的对象应该以消耗的时间来圈定,而不是看到一个很高的获取次数值,当然,获取值异常的高出别的等待时间几十万倍时我们还是要关心的,Oracle关于Latch的等待非常繁多,主要的包括share pool,library cache,cache buffer chains,buffer busy wait

3、如何查看是否存在latch争用
select event,total_waits,time_waited
from v$system_event
where event = ‘latch free’;

4、检查latch free是不是主要的wait event:
Select event,total_waits,time_waited from v$system_event order by time_waited desc;

5、DBA需要关注的latch有:
Select name,gets,misses,sleeps,wait_time,spin_gets,immediate_gets,immediate_misses from v$latch
where name like ‘%shared pool%’
or name like ‘%library cache’
or name like ‘%cache buffers lru chain%’
or name like ‘%cache buffers chains%’
or name like ‘%redo allocation%’
or name like ‘%redo copy%’;

6、锁概述
lock 用来保护对数据的访问的一致性,latch用来保护对内存的访问(latch从不在process之间共享)。
Lock通常发生在许多用户正在少量的表上执行DML操作的时候发生。一旦lock申请获得,lock会一直保留给该用户,直到lock的用户发布一条commit或rollback为止。
一共有两类锁“DML数据锁(Data lock)”和“DDL目录锁(Dictionary lock)”,有两种模式使用锁:“独占型(Exclusive lock)”和“共享型(Share lock)”模式,实现数据的并发性和一致性。

v$lock:报告锁模式等情况。
v$locked_object:报告被锁的对象信息。
dba_waiters:报告阻塞的具体情况,有锁模式,wait session和hold session。
dba_blockers:报告霸占资源导致别的session阻塞的sid.(如果没有,则执行$ORALCE_HOME/rdbms/admin/catblock.sql和utllockt.sql脚本创建)

DML事务使用row-level locks,查询不会锁定数据。锁有两种模式:exlusive、share。
锁的类型:
? DML or data locks:
– Table-level locks(TM的数量一般有init.ora的transactions获,但可修改dml_locks做调整)
– Row-level locks(TX)
? DDL or dictionary locks
一个transaction至少获得两个锁:一个共享的表锁,一个专有的行锁。Oracle server将所有的锁维护在一个队列里,队列跟踪了等待锁的用户、申请锁的类型以及用户的顺序信息。

死锁:
发生死锁后,会自动在$ORACLE_BASE/admin/$ORACLE_SID/udump目录下生成一个详细描述死锁的跟踪文件。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/594892/viewspace-965689/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    44
  • 访问量
    52547