从如何更好的监控Oracle共享池谈起

​二十年前搞Oracle运维的时刻,被折腾得最凶猛的是共享池的疑问,ORA-4031相对是DBA肯定面对的,也是最束手无措的失误。很多DBA面试官也会问少量的共享池诊断与优化的疑问,只管他自己对很多疑问的了解也不过如此。

今早的这篇文章的主体结构是昨天任务前写进去的,今早做了一些补充就收回来了。由于昨天上午我不时在做D-SMART这个局部的优化设计,这篇文章实践上是我这一天任务的一些总结。

Oracle 10G有了SGA灵活调配的才干,而且主机的内存也从MB级别进入到了VLM的级别,共享池和ORA-4031的疑问也就见得少了。在D-SMART里,针对ORA-4031的监控配置比拟少,只提供了一些用于剖析的工具,不过这几年也很少能施展作用。

最近一个客户的数据库由于遇到BUG造成了一个实例发生ORA-4031,肯定重启才干处置疑问。用户提出了针对ORA-4031疑问是否增强监控与剖析。我这几天也不时在思考这个疑问。Oracle数据库中最软弱和最复杂的组件就是SHARED POOL,对SHARED POOL的监控肯定要特意小心。十多年前给用户做Oracle服务的时刻也经常遇到采集SHARED POOL的数据的时刻把数据库实例HANG死的疑问。我甚至养成了采集共享池数据的时刻肯定另外开好另外一个窗口,一旦有疑问立马杀掉采集的会话。

或许很多好友开发的Oracle监控工具里都有共享池监控的配置,他们也感觉监控共享池的手腕是很丰盛的,为什么咱们会把这件事搞得这么复杂呢?

在D-SMART的共享池数据采集方面,我也是十分审慎的,不宿愿由于监控工具设计的不慎而造本钱来负载过高的数据库实例被监控脚本搞垮。在V2.2版本的D-SMART中,和SHARED POOL关系的目的都是经过比拟稳当的系统视图采集的。如今要增强共享池数据的采集,首先想到的就是v$sgastat,由于Oracle的AWR也会采集这个视图里的数据。

为了确认访问的视图的危险,咱们须要找出视图访问的基础数据结构,假设须要少量扫描共享池,那么就应该尽或许防止。经过上方的脚本可以查找关系消息。

SELECT view_definition FROM v$fixed_view_definition WHEREview_name='GV$SGASTAT';

可以看出,GV$SGASTAT的基础视图是x$ksmfs ,x$ksmss ,x$ksmls ,x$ksmjs ,x$ksmns, x$ksmstrs,这些基础数据结构都是汇总KGH的数据的,自身不须要遍历KGH,因此危险都不大。

比如ksmss存储了共享对象的一些属性,只管不会在访问该对象时持有shared pool的闩锁,不过访问环节中也会对共享池内的对象的变卦发生影响。因此只管咱们可以比拟安保的采集数据,不过也不适宜过于频繁。这样的目的的采集,每个小时一次性就可以了。

column indx heading "indx|indx num"

column kghlurcr heading "RECURRENT|CHUNKS"

column kghlutrn heading "TRANSIENT|CHUNKS"

column kghlufsh heading "FLUSHED|CHUNKS"

column kghluops heading "PINS AND|RELEASES"

column kghlunfu heading "ORA-4031|ERRORS"

column kghlunfs heading "LAST ERROR|SIZE"

selectindx,kghlurcr,kghlutrn,kghlufsh,kghluops, kghlunfu,kghlunfsfrom sys.x$kghluwhereinst_id= userenv('Instance')

关于监控共享池的状况来说,kghlu数据结构更为有效,可以十分详细地检查到共享池中的每个子池的统计消息。

特意是kghlunfu/ kghlunfs这两个字段,显示了每个子池发生的ORA-4031失误的次数以及最后一次性调配失误所需调配的空间的大小。普通来说假设在某个子池中调配共享池空间失败只是一个miss,此时会从另外一个池中调配,直到一切的子池中都无法调配空间,才会真正的发生FAILURE。因此ERRORS数量真正指出了共享池内存无法调配空间的状况。对该内存结构的监控可以比拟准确地反映出共享池碎片发生的结果。不过这个数据结构的访问也须要经过关系闩锁,并且这个结构的访问频率要比前面所提的那些结构要频繁。因此对该数据结构的采集依然不倡导过于频繁,一个小时采集一次性曾经足够了。

为什么这样说呢?kghlu中的kghlusep指针是一个十分关键的指针,它指向了共享池LRU链上的一个关键位置,那个位置宰割了共享池LRU链的冷热区。当新的CHUNK要参与LRU链的时刻,是参与在该指针左侧的冷区尾部。而冷区中的CHUNK被屡次访问时会迁徙到LRU链的热端,以便于被重用。因此这个指针是访问十分频繁的,采集该结构的数据要分内审慎。

x$kghlu经常被某些数据库监控软件用来监控共享池疑问,不过频繁的访问这个数据结构还是会对数据库发生影响的,特意是数据库并发比拟大,共享池存在性能疑问的时刻,假设过于频繁的监控这个数据结构,或许会发生一些相当严重的疑问。假设知道了这一点,我想大家应该了解为什么我会对共享池的监控数据采集如此审慎了。

col "avg size" format a30 truncate;

col siz format 999999999999

SELECT KSMCHCLS CLASS, COUNT(KSMCHCLS) NUM, SUM(KSMCHSIZ) SIZ,To_char( ((SUM(KSMCHSIZ) /COUNT(KSMCHCLS) /1024)), '999,999.00')||'k' "AVG SIZE"FROM X$KSMSP GROUP BY KSMCHCLS;

实践上要剖析shared pool的危险,上方的语句具备更好的效果,假设发现perm内存不时增长,free的平均大小不时降低,甚至低于4KB,那么说明共享池发生了较大的碎片化危险。而上方的语句可以作更粗疏的剖析。

col sga_heap format a15

col size format a10

select KSMCHIDX "SubPool", 'sga heap('||KSMCHIDX||',0)'sga_heap,ksmchcom ChunkComment,decode(round(ksmchsiz/1000),0,'0-1K', 1,'1-2K', 2,'2-3K',3,'3-4K',4,'4-5K',5,'5-6k',6,'6-7k',7,'7-8k',8,'8-9k', 9,'9-10k','> 10K') "size" ,count(*),ksmchcls Status, sum(ksmchsiz) Bytesfrom x$ksmspwhere KSMCHCOM = 'free memory'group by ksmchidx, ksmchcls,'sga heap('|| KSMCHIDX||',0)',ksmchcom, ksmchcls,decode(round(ksmchsiz/1000),0,'0-1K',1,'1-2K', 2,'2-3K', 3,'3-4K',4,'4-5K',5,'5-6k',6,'6-7k',7,'7-8k',8,'8-9k', 9,'9-10k','> 10K');

这条SQL可以采集到共享池中free内存的详细状况,假设较大的heap比拟少时,共享池的碎片化就很严重了。

仿佛咱们可以间接对x$ksmsp间接做采集,从而取得对共享池剖析的更有效的数据。不过真的如此吗?咱们假设看一下x$ksmsp的实践结构,就会明确为什么咱们不想把这个采集放到智能化采集的脚本中,更好的采集共享池的消息了。

咱们可以看到ksmsp实践上指向了一个kghds的链表,而这个链表实践上是指向实在的heap链,对x$ksmsp的统计实践上会遍历heap链表,关于共享池很大,并且共享池并发访问很重,特意是共享池存在性能疑问的场景,这种访问无疑会减轻共享池的累赘,甚至成为压垮骆驼的最后一根稻草。假设这种采集放到不受控的智能化采集中去,那或许会带来无法知的影响。因此这种剖析咱们只是在手工点击的工具中提供,而不会做成智能化采集的一局部。

监控与诊断实践上也是一种运维常识,开发监控与诊断工具,产品经理中应该有资深的运维专家,仅仅依托高水平的研发人员是开发不出一套真正高水平的运维监控与诊断工具的。而关于一些比拟软弱的数据库模块的监控采集,也须要十分审慎的做设计,否则监控软件会成为伪装成天使的恶魔。

您可能还会对下面的文章感兴趣: