latches 闩
sga中许多内存结构,需要oracle实例的数据库进程并发访问。但每一个时刻只能一个进程去修改它们。
因此oracle通过latches或lock来保护sga数据结构不被破坏.
latches比lock的限制措施更多,它不允许多个进程同时检查所要保护的数据结构,它们提供了排它访问.然而
locks可以支持更好的并发,因为它们可以被共享模式持有(如果数据结构只是被检查).
(这意味着redo copy latches可以被共享,但与硬件相关)
另一种二者重要区别就是,请求排队机制。如果以某种必要或顺序请求某个locks,它们被先排队.但latches不支持请求排队。
如果请求一个latch失败,因为这个latch正在忙。此时进程就直接重试直至成功得到latch.因此latch请求不一定(没必要)依序服务.
因为一个latch在同一个时间只能被一个进程持有,也没有排队这一说,latch数据结构本身很简单,从本质上讲,它只是用内存一个区域表示latch的状态而已。
因为latch数据结构简单,所以请求及free它基本不用作什么工作(也就是不用花费过多的资源)。相比之下,locks的数据结构更为复杂,因为要支持排队及并发。
因此请求,转化,free它需要更多的工作要作.
另一方面,oracle lock数据结构,有几个部分,因此不能以原子性方式去修改它.从这个事情来讲,oracle实际上用latch来保护对于locks的操作。当然使用什么类型的
latch,这与lock类型有关。比如,cache buffer locks间接被cache buffers chain latches来保护,row cache enqueue lock被row cache object latch所保护.
由于latches的高效性,oracle经常使用它,而非lock。
parent and child latches 父与子latch
大多数内部的oracle数据结构,用一个latch就可以保护它了。但是,在一些情况下,需要多个latch。比如,为了保护library cache之中不同group的对象,需要好多library cache latches。
每个cache buffers chain latches保护每个database buffer cache hash chain.
当出现多个latches保护一个结构(内部oracle数据结构),或者不同的等同结构,这些latch叫作child latches.对于相同类型的child latches的每个集合,也有一个parent latch.一般来讲,
parent和child latches可能都需要了。但实际上,你可能只想得到这个library cache parent latch,甚至很少发生请示child latches(相比活动而言).
大家看了以上,可能有点晕了,oracle也引用单独(独立的)的latch直接作parent latch,它并没有child latch.因此v$latch_parent中,每种单独的latch,只有一行记录.每一个真正的parent
latches也是只有一行记录.v$latch_children对于每个child latch只有一行记录。因此这两个视图的合并会显示所有的latches.
顺着oracle版本的不同,会使用不同类型的latches,它们可能是单独或parent及child latches.
v$latch根据每种latch显示latch的概要信息。它应是你第一个关注的地方(latch问题).如果发现是相同类型的latch集合,这下你就可以查看v$latch_children分析在child latches的活动是否均匀,
通过v$latch_parent也会帮助你是否基于某个parent latch的活动有问题呢?
latch gets 请求latch
当oracle进程访问数据结构需要一个latch时,可以两种方式get它,乐观等待模式及悲观等待模式(也叫立即模式)
乐观等待模式
发现latch不可用,马上短暂spin然后再次尝试get.当一个进程spins,它多次执行一系列简单的指令,作为在重新尝试get前的一种等待方法。从os的层面把这叫作一个活动的等待,因为进程仍旧在占用cpu的周期,虽然它只是等待了一会.
尝试再次get latch之前所花费的cpu time,很小及固定。(虽然在oracle7i用_latch_spin_count可以调节)。如果下次get latch又失败了。这个过程或动作(spin)会一直持续到_spin_count参数的值.这个参数默认是2000 次重复(在多处理器环境中)
why spin? 为何要spin呢
spinning这种思想,源于另一个进程在另一个cpu执行时,可能会释放这个latch,因而允许spinning 进程继贯执行。当然,如果仅一个cpu,这样作毫无意义.
替代spinning的另一种方法,这个进程不用cpu了,让另一个进程使用。初看,这是个好主意.但是,对于cpu而言,它要停止执行一个进程,而开始执行另一个进程,它必须进行一个上下文切锦。也就是说,它要保存第一个停止进程的上下文信息,用此确定下次调度哪个进程,然后
恢复下一个进程的上下文。一个进程的上下文,其实就是一系列的cpu注册值(用此表示这个进程的准确状态).
上下文切换实施与具体的机器高度相关。事实上,典型它用汇编方式写的。system供应商力求最小化上下文数据的大小,通过使用trick比如重映射内存地址而非拷贝数据来优它上下文切换.但是,上下文切换仍旧是一个昂贵的操作,因为各种各样的内核数据结构要被查找并更新.
访问这些结构通过spinlocks的来保护,spinlocks就是os级的latches.在一个大量高负荷的system中,上下文切换正常会占用1-3%左右的cpu时间.因此短暂的spinning可以避免它。这样可以节省cpu time,进而请求latch的等待时间也会减少.基于以上原因,短暂spinning相对放弃cpu(马上)更为明智.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9240380/viewspace-660126/
,如需转载,请注明出处,否则将追究法律责任。