故障排除步骤
什么是“library cache: mutex X”等待?
mutex功能是一种控制内存结构访问的机制,广泛应用于包括library cache在内的多个区域。library cache是一个存储解析cursor结构的内存区域,这些结构是执行SQL所需的。
“library cache: mutex X”等待与早期版本中的library cache等待类似。“library cache: mutex X”可能由许多问题引起(包括应用程序问题、共享不足导致的高版本计数等),但基本上是某些操作占用互斥体的时间过长,导致其他会话不得不等待该资源。如果保护library cache结构的latches/mutexes存在争用,这意味着解析系统受到压力。SQL解析时间变长,因为无法获得所需资源。这会延迟其他操作,并普遍减慢系统速度。
由于原因多样,找到正确的原因很重要,以便实施合适的解决方案。
引起“library cache: mutex X”等待的原因?
「频繁的硬解析」:如果硬解析的频率极高,则会在此锁上发生争用。
「高版本计数」:当版本计数过多时,需要检查长版本链,这可能导致此事件的争用。
「无效化」:无效化是指缓存的游标由于不再有效而被删除。当某些更改导致内存中的游标副本无效时,游标会无效。例如,重新收集对象上的统计信息或修改表定义足以使基于该对象的查询游标无效。当游标无效时,任何想使用该游标的会话都需要等待加载有效版本。如果无效化过多或不必要,则可能会看到显著的“library cache: mutex X”等待。
「重新加载」:重新加载是指缓存中之前存在的游标被搜索到不存在,然后必须重新编译并重新加载到library cache中的次数。高重新加载是不好的,因为它表示如果缓存设置适当,最初不需要删除游标时,你正在做不必要的工作。如果游标被重新加载,则会话无法获取,这可能导致“library cache: mutex X”等待。
诊断原因的方法
「检查是否有任何变化:」
负载增加了吗?
应用程序、操作系统或中间层有任何变化吗?
操作系统有任何变化吗?
「是否有“library cache: mutex X”等待的趋势:」
是否在一天中的某个特定时间看到此等待?
是否有某些触发此等待的事件?
「在问题发生时,运行AWR和ADDM。还需获取基线以比较负载、参数变化和其他差异。建议每半小时到一小时运行AWR和ADDM:」
SQL> @$ORACLE_HOME/rdbms/admin/awrrpt.sql
SQL> @$ORACLE_HOME/rdbms/admin/addmrpt.sql
「有时系统状态转储是必要的,以匹配已知问题。例如,如果在AWR中没有明显的候选SQL,捕获systemstate中的持有者或等待进程可以让你关注潜在问题。当进程在“library cache: mutex X”上似乎挂起时,运行systemstate:」
「(a) 非RAC」
sqlplus "/ as sysdba"
oradebug setmypid
oradebug unlimit
oradebug dump systemstate 266
<wait 90 seconds>
oradebug dump systemstate 266
<wait 90 seconds>
oradebug dump systemstate 266
quit
**(b) RAC**
$ sqlplus '/ as sysdba'
oradebug setmypid
oradebug unlimit
oradebug setinst all
oradebug -g all hanganalyze 4
oradebug -g all dump systemstate 266
quit
「错误堆栈:获取进程信息的另一种方法是使用错误堆栈。假设可以识别出阻塞者,则获取错误堆栈将提供与systemstate相同的信息,但磁盘占用更少。找到阻塞者的ospid后,可以生成错误堆栈:」
SQL> oradebug setospid <p.spid from above>
oradebug dump errorstack 3
<< wait 1min>>
oradebug dump errorstack 3
<< wait 1min>>
oradebug dump errorstack 3
exit
「有时运行systemstate转储不可行,因为它可能资源密集。可以间隔运行以下SQL:」
select s.sid, t.sql_text
from v$session s, v$sql t
where s.event like '%mutex%'
and t.sql_id = s.sql_id
检查诊断信息的方法
通常,主要等待事件将在问题AWR中显示为library cache: mutex X。

首先从AWR中检查高解析和高版本计数: 点击AWR主报告下的SQL Statistics。

然后,在SQL Statistics下点击'SQL ordered by Parse Calls'和'SQL ordered by Version Count'查看信息:

检查高解析调用。

检查是否有高解析调用执行。理想情况下,解析与执行的比例应较低。如果解析与执行次数相同,则表明应用程序没有很好地使用游标。一旦打开并解析游标,应保持其打开状态。与应用程序开发人员确认如何保持游标打开以重新执行SQL。
接下来,检查SQL的版本计数: 从列表中调查高版本计数的SQL。这些语句为何不能共享?是否可以解决此问题?

潜在的解决方案
「检查高硬解析」,因为这可能导致SQL区域的重新加载。在负载配置文件下检查硬解析:

这表明每秒26.3次硬解析,表示硬解析频率高。检查应用程序是否共享SQL。
此外,查看这个部分

如果有大量重新加载,则查看游标是否被有效共享(记住重新加载计数的是曾经缓存但现在不再存在的游标)。如果是,则检查shared pool或sga_target是否足够大;游标可能因空间不足而老化。记住,非有效共享意味着library cache将充满不可重用的游标,这可能导致可重用的游标被冲出。这些游标在重新执行时会导致重新加载。 如果共享有效且shared pool太小,则共享SQL语句会老化,硬解析会更高。然而,在大多数情况下,问题在于共享效率低。
「在Library Cache活动下检查无效化」。如果无效化次数高,则检查期间执行的DDL操作,如截断、删除、授予、dbms_stats等。
「对于11g,确保cursor_sharing不是similar」,因为它已被弃用。这也可能导致互斥体等待
总结
library cache: mutex X
等待事件是 Oracle 数据库性能调优中的一个重要方面。通过优化 SQL 解析、增加库缓存、合理管理库缓存对象,以及调整库缓存参数,可以有效减少该等待事件,提升数据库整体性能。
「欢迎关注我们的公众号,获取更多技术分享与经验交流。」




