一、说在前面
Prometheus新的监控刚刚上线,今天在库里就看见了它的痕迹,可见定制的监控纵然灵活轻便,但是不过硬的SQL一不留神就能拉倒你的库。二、事情经过
事情是这样的,由于近期在系统研究SQL优化,所以比较频繁的刷新数据库的等待事件。今天在检查DG从库等待事件的时候发现有两个语句和平时有些不一样,等待事件显示latch:row cache object,明显存在问题。三、分析过程
由于这两个语句为每天执行的报表查询,平日表现虽慢但还算乖巧,所以分析问题应该不在这两个语句上,同时发现有大量Prometheus的监控语句正在执行,等待事件显示为direct path read,怀疑是全表扫描,进一步查询发现监控的渠道为昨日新上线内容,故认定入口就在这里。
此时在服务器的IO上也发现了些许异常,执行语句数量并不多,IO却略高出平日水平,也并无降低的意思,同时CPU也有小幅上升,基本上判断就是direct path read和latch:row cache object的锅了。通过查询数据库IO的TopSQL,发现Prometheus的两条语句占用整体IO的65%,且执行数量较大,等待事件为direct path read,判断可能这两条语句存在大量的硬解析,导致了latch:row cache object的发生。
通过SQL_ID查询语句执行计划,发现语句主表果然是全表扫描,产生COST值*[并非准确值]惊人。
查询此表数据分布发现,此表存在3000万行数据,而全表扫描筛选仅返回7万行结果,同时筛选列setl_val_dt的数据分布较为平均,这个选择度,这个分布情况,啧,应该走索引的。同时谓词条件里的另一个条件paym_ind=‘N’的筛选值在13%左右,考虑可以创建一个复合索引。

四、说干就干
基于所有线索的判断,创建了一个针对这两列的复合索引,再次查看执行计划,COST值*[并非准确值]下降了近300倍。
至此优化完成,在latch:row cache object未造成严重问题前,解决战斗。

五、关于几点不严谨的地方
本文查询执行计划均是使用explain plan for进行查询,但是explain plan for只产生执行计划,而不是真正执行语句,所以其从plan_table中查询的执行计划并不一定准确,毕竟没有真的执行。
而在这种情况下执行计划里的COST值也不是准的,是Oracle代价评估器估算出来逗你玩的,所以仅供参考切勿以此为依据去严谨推断。
六、关于等待事件direct path read与全表扫描
等待事件direct path read,一般是并行全表扫描导致,一般情况下是多块读,Oracle 11g的特性,在对一个大表全表扫描的时候,会将表直接读入PGA,绕过buffer cache,这个时候全表扫描的等待事件也会是direct path read。而全表扫描的等待事件一般是db file scattered read,一般情况下也是多块读。值得注意的是,等待事件direct path read在开启了异步IO(参数为disk_asynch_io)的情况下统计是不准确的。同时针对disk_asynch_io还有一个bug,bug号为9829397,等待事件为Asynch decriptor resize,为异步IO写入问题。官方解释为:Excessive CPU and many ‘asynch descriptor resize' wait for SQL using Async IO。解决方法是将此参数设置为false。七、关于等待事件latch:row cache object与硬解析
官方文档对于这个等待事件是这么解释的:latch:row cache object,This latch comes into play when user processes are attempting to access or update the cached data dictionary values。说的这个latch的问题是对象的数据字典。
那么本次问题其实在于多数的监控SQL为第一次执行,硬解析严重。而硬解析需要去获取数据字典资源,这是要获得latch的。那么当硬解析数量过大,latch发生严重争用,进而导致CPU使用率升高,而由于执行的语句均在等待latch的释放,IO反而影响不大,甚至可能会低于基线。表现在数据库上即为row cache object等待事件。
之前遇到的情况要比这次更为典型,事故发生时数据库系统缓慢,数据库中多个语句等待事件显示为latch:row cache object,同时文件系统CPU的使用率较高,IO的异常并不是很明显。显然这种情况是因为大量SQL未使用绑定变量,将SQL改为绑定变量,将硬解析变为软解析,减少获取数据字典的次数,降低latch的争用,进而从根本上解决了问题。
