简单案例说明: 某运营商的客服系统在有几天遭遇业务高峰的时候,发生大量row cache object latch冲突,导致客服响应延迟甚至阻塞。通过flush shared_pool有所缓解,但是很快又到达高峰,即使重新启动数据库也很快会达到高峰导致业务系统阻塞。一旦度过高峰期,业务系统恢复正常。查询系统表现出了相对较高的SQL Version,主要SQL版本上公共同义词进行访问,公共同义词依据经验会提供几倍的row cache object latch访问。代码修复为owner.table访问之后,该阻塞问题得到解决。
latch free是大家在日常性能处理遇到最为主要的性能障碍,大家遇到的比较多的有:library cache,shared_pool,row cache object,cache buffer chain等。
认识latch:
latch是一种轻量锁,用来保护Oracle的内存结构。Oracle内存结构需要实现串行化访问,需要通过latch来保护。编码的人都知道,要保护一个内存结构,最简单的1bit就可以满足。Oracle latch是相对比较重的结构,大约有100~200字节。遗憾的是,我也不知道latch数据结构保存些什么东西,当然不知道其结构并不会对于你性能优化带来多大障碍,属于有可以吹牛,没有也没有损失的知识领域。
既然是一种串行机制,一个内存结构上自然只有一个latch来进行保护。
我们来看latch使用:
get latch
holding latch
release latch
从get latch而言,我们事实上有两种选择:spin or post,spin消耗CPU资源,但是具有最快获得效果,一旦没有获得其CPU资源就属于白白浪费,资源利用的效率是比较低的。post,采用唤醒机制,自然资源利用效率比较高,但涉及到上下文切换,自然其效率比较低。如果采用post机制,无非是两种方式,一种是定向广播,一种是无目的广播。如果是定向广播,事实上就需要在latch结构中实现一个缓冲区用来存储广播对象。总共100多字节的大小,显然不可能存储所有的广播对象。
从资源利用角度而言,我还是支持latch具有某种post机制,否则按照一般理解的说法:
get-spin-sleep-get-spin-sleep,Oracle采用了流行的弱者牺牲模式,你越是无法获得latch,你sleep的时间将会越长,主动的sleep模式的最大问题就是在latch已经没有人使用了,sleep进程也要等待sleep间隔到达然后去检测latch是否可用。从这点上考虑,我深信Oracle latch post机制是存在的。
从我的性能优化体系来讲,latch是衡量负载压力的极为重要的一部分,我把latch gets等同于logical reads,physical reads等完全一样的压力负载衡量方式,完全遵循吞吐量曲线,当达到一定的latch gets之后,业务系统性能会必然快速变差。
ok,我们来看几个最为重要的latch:
shared pool
shared pool
library cache (11g已经迁移到了mutex)
row cache object latch
buffer cache
cache buffer chain
我们关注latch的以下重点:
latch gets
spin gets
latch misses
sleeps
在这里,从性能体系角度上来说,我最为关心latch gets+latch misses,其体现了内存访问的整体压力,一旦压力超过其极限,必然会出现大量latch misses和sleeps,latch miss和latch sleeps只不过是latch gets达到限制之后必然反映。我们多年来在性能优化方面的实践不断的在验证这个观点的正确性。
既然如此,优化latch问题的入手方法也就比较简单了:
(1)、降低latch gets数量
(2)、分布热点到其他同类的latch,也就是Oracle一直在latch领域的努力,内存数据结构细分以求获得更多的latch保护。
(3)、降低latch持有时间
当然这里发生了悲剧的事情,当latch被mutex取代的时候,Oracle上层无法获得mutex gets的值,使我们无法来评估mutex的整体压力。mutex从体系设计来讲是个进步,从性能优化的可能性来说是个退步,在后面章节会讲mutex。
我们来看看常见的几个Oracle latch锁保护的内存结构:
shared_pool
保护shared_pool的空闲空间列表,管理空闲空间的减少和增加。和所有的空间分配一样,比如表空间的Extent扩展,全局都被一个shared_pool所保护。
降低latch gets: 降低hard parse,
enough free space
热点分布:subpool
降低latch持有时间:降低碎片
足够的空闲空间。
内存访问足够快
顺便提一下,在任何时候保持足够的shared_pool是Oracle性能的最基本保障,太多太多的性能问题是由于shared_pool不足引起(碎片化)。
library cache
library cache是一个相当复杂的结构,不同于shared_pool latch所保护的简单结构,不可能由一个latch来保护整个复杂结构,Oracle把复杂结构细分成很多成相互关联的独立内存结构,在每个独立结构上施加library cache latch保护,不仅如此,Oracle把巨大的同类library cache分片,通过分片划分更多的内存结构,每片被不同的latch所保护,以增加巨大的并发性需求。
降低latch gets:降低hard parse
cache cursor到uga层
热点分布: library cache获得更大的分片
降低持有时间: 降低hash bucket中的数量
降低children table数量
足够的空闲空间
内存访问足够快
row cache object latch:
降低latch gets:降低hard parse
降低sql version
cache cursor到uga层
热点分布: 无法分布,降低latch gets
降低持有时间: 足够的空闲空间
降低sql version
buffer cache访问足够快
内存访问足够快
降低管理对象
cache buffer chain:
降低latch gets:降低逻辑读数量
热点分布: 更大的分片
加大buffer cache
降低持有时间: 更大的分片,降低latch保护的范畴
控制cr block
足够快的内存访问
足够大的buffer cache
最后再次重新申明一下,在任何时候latch gets+latch miss是最为重要的latch指标,而不是latch misses,降低latch gets+latch miss是最重要的latch优化手段,而不是分配更多的latch。
latch free是大家在日常性能处理遇到最为主要的性能障碍,大家遇到的比较多的有:library cache,shared_pool,row cache object,cache buffer chain等。
认识latch:
latch是一种轻量锁,用来保护Oracle的内存结构。Oracle内存结构需要实现串行化访问,需要通过latch来保护。编码的人都知道,要保护一个内存结构,最简单的1bit就可以满足。Oracle latch是相对比较重的结构,大约有100~200字节。遗憾的是,我也不知道latch数据结构保存些什么东西,当然不知道其结构并不会对于你性能优化带来多大障碍,属于有可以吹牛,没有也没有损失的知识领域。
既然是一种串行机制,一个内存结构上自然只有一个latch来进行保护。
我们来看latch使用:
get latch
holding latch
release latch
从get latch而言,我们事实上有两种选择:spin or post,spin消耗CPU资源,但是具有最快获得效果,一旦没有获得其CPU资源就属于白白浪费,资源利用的效率是比较低的。post,采用唤醒机制,自然资源利用效率比较高,但涉及到上下文切换,自然其效率比较低。如果采用post机制,无非是两种方式,一种是定向广播,一种是无目的广播。如果是定向广播,事实上就需要在latch结构中实现一个缓冲区用来存储广播对象。总共100多字节的大小,显然不可能存储所有的广播对象。
从资源利用角度而言,我还是支持latch具有某种post机制,否则按照一般理解的说法:
get-spin-sleep-get-spin-sleep,Oracle采用了流行的弱者牺牲模式,你越是无法获得latch,你sleep的时间将会越长,主动的sleep模式的最大问题就是在latch已经没有人使用了,sleep进程也要等待sleep间隔到达然后去检测latch是否可用。从这点上考虑,我深信Oracle latch post机制是存在的。
从我的性能优化体系来讲,latch是衡量负载压力的极为重要的一部分,我把latch gets等同于logical reads,physical reads等完全一样的压力负载衡量方式,完全遵循吞吐量曲线,当达到一定的latch gets之后,业务系统性能会必然快速变差。
ok,我们来看几个最为重要的latch:
shared pool
shared pool
library cache (11g已经迁移到了mutex)
row cache object latch
buffer cache
cache buffer chain
我们关注latch的以下重点:
latch gets
spin gets
latch misses
sleeps
在这里,从性能体系角度上来说,我最为关心latch gets+latch misses,其体现了内存访问的整体压力,一旦压力超过其极限,必然会出现大量latch misses和sleeps,latch miss和latch sleeps只不过是latch gets达到限制之后必然反映。我们多年来在性能优化方面的实践不断的在验证这个观点的正确性。
既然如此,优化latch问题的入手方法也就比较简单了:
(1)、降低latch gets数量
(2)、分布热点到其他同类的latch,也就是Oracle一直在latch领域的努力,内存数据结构细分以求获得更多的latch保护。
(3)、降低latch持有时间
当然这里发生了悲剧的事情,当latch被mutex取代的时候,Oracle上层无法获得mutex gets的值,使我们无法来评估mutex的整体压力。mutex从体系设计来讲是个进步,从性能优化的可能性来说是个退步,在后面章节会讲mutex。
我们来看看常见的几个Oracle latch锁保护的内存结构:
shared_pool
保护shared_pool的空闲空间列表,管理空闲空间的减少和增加。和所有的空间分配一样,比如表空间的Extent扩展,全局都被一个shared_pool所保护。
降低latch gets: 降低hard parse,
enough free space
热点分布:subpool
降低latch持有时间:降低碎片
足够的空闲空间。
内存访问足够快
顺便提一下,在任何时候保持足够的shared_pool是Oracle性能的最基本保障,太多太多的性能问题是由于shared_pool不足引起(碎片化)。
library cache
library cache是一个相当复杂的结构,不同于shared_pool latch所保护的简单结构,不可能由一个latch来保护整个复杂结构,Oracle把复杂结构细分成很多成相互关联的独立内存结构,在每个独立结构上施加library cache latch保护,不仅如此,Oracle把巨大的同类library cache分片,通过分片划分更多的内存结构,每片被不同的latch所保护,以增加巨大的并发性需求。
降低latch gets:降低hard parse
cache cursor到uga层
热点分布: library cache获得更大的分片
降低持有时间: 降低hash bucket中的数量
降低children table数量
足够的空闲空间
内存访问足够快
row cache object latch:
降低latch gets:降低hard parse
降低sql version
cache cursor到uga层
热点分布: 无法分布,降低latch gets
降低持有时间: 足够的空闲空间
降低sql version
buffer cache访问足够快
内存访问足够快
降低管理对象
cache buffer chain:
降低latch gets:降低逻辑读数量
热点分布: 更大的分片
加大buffer cache
降低持有时间: 更大的分片,降低latch保护的范畴
控制cr block
足够快的内存访问
足够大的buffer cache
最后再次重新申明一下,在任何时候latch gets+latch miss是最为重要的latch指标,而不是latch misses,降低latch gets+latch miss是最重要的latch优化手段,而不是分配更多的latch。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/92650/viewspace-1062722/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/92650/viewspace-1062722/