oracle故障处理之cursor: mutex X分析

最近一套12C库出现大量cursor:mutex X异常等待的故障,借此机会在这里和大家分享下分析过程及后续处理。先简单介绍下故障过程,一天数据库突然等待事件异常告警,登上数据库查看异常等待事件发现大量cursor:mutex X,基于优先恢复业务的原则,将其kill之后数据库恢复正常。后续开始对故障进行分析及进行后续处理,欲知详情,请听下面分解。

1、查看故障时段AWR:
oracle故障处理之cursor: mutex X分析

发现cursor:mutex X异常等待事件占了54%的DBTIME

2、cursor:mutexx等待事件原理:

cursor正在被解析并尝试以独占(exclusive)模式获取cursormutex时产生的等待即为cursor:mutexx。


引起问题的原因包括频繁硬解析、highversioncount、cursor失效及未知BUG等。但本质上是一些会话长时间持有互斥锁,以至于其他会话不得不等待资源。如果在保护库缓存结构的latches/mutexes上发生争用,这意味着解析面临压力。解析SQL需要更长的时间,因为它无法获得所需的资源。这会延迟其他操作,并且通常会降低系统的速度。

查看问题刚出现时的历史会话(DBA_HIST_ACTIVE_SESS_HISTORY)如下:

oracle故障处理之cursor: mutex X分析

从上图我们可以看到多个会话同时执行SQL_ID:3t5xt2hkrchpy,a9xqubd880h5n,且堵塞源不停在变,会话相互之间发生cursor:mutex X等待。

3、查看故障时段的AWR:

oracle故障处理之cursor: mutex X分析
oracle故障处理之cursor: mutex X分析
oracle故障处理之cursor: mutex X分析

从以上图我们可以看到SQL_ID:3t5xt2hkrchpy执行时间及CPU消耗TOP1,其SQL及其他SQL的版本数都很高。

4、查看故障时段做的hang分析日志如下:

oracle故障处理之cursor: mutex X分析
oracle故障处理之cursor: mutex X分析
oracle故障处理之cursor: mutex X分析
oracle故障处理之cursor: mutex X分析
oracle故障处理之cursor: mutex X分析

通过hang分析日志我们可以看到Blcoking其他session的会话操作是查找子Currsor,所以故障大概率是由于子Cursor过多,进行查找时发生等待导致。而产生大量的子Cursor的原因是NLSSettings。

普及下什么是versioncount?

一个SQL第一次执行时,会进行硬解析,同时创建parentcursor和childcursor。

当这个SQL时再次执行时,首先会对SQL语句进行特殊的hash运算,对应生成一个hashvalue。Hashvalue存放在parentcursor中,然后会用这个hashvalue到paranetcursor的bucket中匹配,如果相同的hashvalue 已存在parentcursor里,则继续遍历这个childcursor,如果可重用,那么就沿用childcursor的信息,如果不能重用,就会重新生成一个新的childcursor。一个parentcursor下childcursor的总数,就是这个SQL的versioncount。

highversion count指的就是childcursor总数很高。在AWR报告中,默认verioncount超过20的SQL就会显示在orderby version count中。根据经验versioncount如果超过100,可能就需要引起注意了。

5、综上所述,我们发现本次故障大概率是由于highversion count导致,那为啥这么多SQL的versioncount都这么高呢,初步怀疑是触发BUG了,我们这库是CDB模式,并且多个PDB的字符集不一致,通过MOS查找到一篇类似的文章:

oracle故障处理之cursor: mutex X分析

通过SR确认有可能触发BUG25054064,该BUG在2020年1月份的DBRU中fixed了,我们只需要打上

Patch31741641: DATABASE OCT 2020 RELEASEUPDATE12.2.0.1.201020即可,因为DBRU都是累积的。

查看其readme提供的BUG修复的连接发现BUG25054064已在补丁集中。

oracle故障处理之cursor: mutex X分析

6、打完补丁之后截止目前为止再没出现过类似的故障,我们查看SQL的versioncount发现降低了一个数量级。

oracle故障处理之cursor: mutex X分析

另外由于字符集不匹配导致的highversion count在DocID 2542447.1也详细介绍了处理方法,用于缓解子Cursor过多查找缓慢导致的等待:

1)通过具体SQL_ID将其从sharedpool清除掉。

SQL>select address,hash_value,version_count from v$sqlarea wheresql_id=’a9x5sbz88kmfh’;

ADDRESSHASH_VALUE VERSION_COUNT
—————- ———————–
000000006BFFAC00 3498659280 2

SQL>exec dbms_shared_pool.purge(‘<address,hash_value>’,’C’);
Ex:
SQL>exec dbms_shared_pool.purge(‘000000006BFFAC00,3498659280′,’C’);

PL/SQLprocedure successfully completed.

2)将_cursor_obsolete_threshold参数设置为较低的值减少子Cursor数量,不过这个取决于应用程序需求,_cursor_obsolete_threshold的默认值是8192,可以将其设置为2048或1024,重启生效。

来源:IT那活儿,本文观点不代表自营销立场,网址:https://www.zyxiao.com/p/104701

发表评论

登录后才能评论
侵权联系
返回顶部