latch sleep后唤醒方式:
1.sclgts() slow方式唤醒 , timeout方式,timeout由一个内部参数控制_MAX_EXPONENTIAL_SLEEP,默认是2秒,第一次默认是1/100秒
在v$latch视图中有sleep1到11,这里举例如果sleep了3次,那么sleep1+1,sleep2+1,sleep3+1,这里只记录11次的
2.sclgtf() fast方式唤醒 , 需要获取latch wait list来唤醒
这里如果有一个进程持有其他的latch,还需要再获取另外一个latch,最长睡眠时间就不是上面_MAX_EXPONENTIAL_SLEEP的两秒,而是,_max_sleep_holding_latch,默认是4厘秒,这里为什么缩短进程的休眠时间,可能是因为进程的休眠比获取更费CPU资源,为什么呢,比如其他进程等待该休眠的进程所持有的latch,如果持有该latch的进程还在等别人,那不是等的时间更久。
上面都是willing to wait模式的
下面看下no wait模式的:
no wait在少量的latch中使用,no-wait模式获取latch的统计信息记录在immediate_gets和immediate_misses列中,就是之前介绍的三个视图中,比如redo-copy latch,如果进程获取子latch失败,那么就会获取下一个子latch,采用no wait,直到所有的子latch都失败,那么转回willing to wait。
latch level(优先级)
每个latch都有0~15,16个优先级编号,父latch和独立latch是固化在oracle内核代码中的,子latch是实例启动时候创建,集成父latch的优先级编号。在oracle中,只有申请比自己持有的latch优先级高的latch才可以,因为优先级高,影响的范围更大,所以要先处理,早点处理,早点释放资源。
_spin_count:这个相当于之前CPU帮你看的次数,如果设置过短的话,那么碰到长时间持有的latch,那是不是要经常sleep,sleep是不是很耗资源,所以这个值如果调大,那么就减少了sleep和misses的次数,代价是花费了更多的CPU时间。
x$ksllclass包含了latch的八种类信息,通过查询这个视图,可以修改相应的的参数,来修改spin_count值。
通过查询v$latchname 可以查到相关latch的name和latch号,然后修改相应的初始化参数
select latch#,name from v$latchname where name like '%cache%';
LATCH# NAME
---------- --------------------------------------------------
12 cached attr list
64 ges caches resource lists
117 cache buffers lru chain
122 cache buffers chains
123 cache buffer handles
125 cache protection latch
126 cache table scan latch
156 logical standby cache
168 flashback marker cache
186 file cache latch
198 sequence cache
200 row cache objects
209 OLS label cache
215 library cache
216 library cache lock
217 library cache pin
218 library cache pin allocation
219 library cache lock allocation
220 library cache load lock
221 library cache hash chains
333 KWQMN job cache list latch
这里看到标红的latch号和名称,然后修改相关的初始化参数
_latch_class_1 = "10000" ---将类型为1的spin_count值改为10000
_latch_classes = "122:1" ------将编号为122的latch分派到类型1
查询x$ksllclass就可以看到修改结果,现在的默认值都是20000。
注意这些参数不能随意修改,如果CPU资源比较紧张那就更不能加大该值。
想降低latch的争用,关键还在SQL上,所以SQL调优是很重要的。
latch free:当进程spin后,还是没有获取latch后,进入sleep状态,这时就出现latch free状态,V$system_event视图的total_waits列记录了进程获取latch失败的次数,所以这里total_waits的值和v$latch中sleep值的总和应该是差不多的。
latch争用:
1.高CPU占用,这个好理解,如果一个持有latch的进程不能很快获得使用CPU的时间片,那么无法避免的肯定产生大量等待。
2.oracle latch长时间被占用。比如共享池碎片太多,太大造成空闲列表过长等等。
3.latch请求太频繁导致。比如commit频繁,造成redo allocation latch的争用,可以通过增加子latch来缓解,这个可以查询v$latch_children来查看,也可以不要commit太频繁