【Latch】的理解

latch获取相关概念
1. 自旋(spin)
2. 休眠(Sleep)
3. 上下文切换(Context Switch)

如何获取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,进行短暂的休眠,再继续刚才的动作。

当尝试获得Latch的时候,可能会消耗大量的CPU时间,系统看上去很忙,但是并没有做多少实际工作。

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

Oracle使用两种数据结构来进行shared pool的并发控制:lock和pin。Lock比pin具有更高的级别,Lock在handle上获得,在pin一个对象之前,必须首先获得该handle的lock。
Lock主要有三种模式:Null、share、Exclusive。在读取访问对象时,通常需要获取Null(空)模式以及share(共享)模式的锁定;在修改对象时,需要获得Exclusive(排他)锁定。

在锁定了Library Cache对象以后,一个进程在访问之前必须pin该对象。同样pin有三种模式:Null、shared、exclusive。只读模式时获得共享pin,修改模式获得排他pin。
    通常我们访问、执行过程、Package时获得的都是共享pin,如果排他pin被持有,那么数据库此时就要产生等待。

闩锁和锁定既有相同点又有不同点。相同点在于它们都是用于实现串行化的资源。而不同点则在于闩锁(Latch)是一个低级别、轻量级的锁,获得和释放的速度很快,以类似于信号灯的方式实现。而锁定(Lock)则可能持续的时间很长,通过使用队列,按照先进先出的方式实现。也可以简单地理解为闩锁是微观领域的,而锁定则是宏观领域的。

Latch的类型:

  1. Willing-to-wait类型Latch:

    如果一个进程在第一次尝试中没有获得该Latch,那么它会等待并再次尝试一次,如果 经过_spin_count次争夺不能获得Latch,该进程就会转入睡眠状态,睡眠结束后,按顺序重复之前的步骤,并且睡眠时间会越来越长。
    
  2. Immediate类型Latch:

     如果该Latch不能立即得到,该进程不会等待而是继续执行其他操作
    

– The End –

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值