导读
上一篇文章介绍了latch争用的相关内容,本文继续介绍与latch相关的mutex争用的相关内容。
1、Mutex故障排除
查看相关视图
v$session
V$SESSION_WAIT
P1,P2,P3值表示library cache 对象在争用状态下的哈希值,即持有mutex的会话。
V$event_name和V$session_wait的 "text"列记录了P1, P2, P3
从上面的视图中,可以查看到相关的mutex等待事件:
• cursor: mutex S
• cursor: mutex X
• library cache: mutex S
• library cache: mutex X
V$MUTEX_SLEEP :显示等待时间,以及每个mutex类型和位置组合的sleep次数。
V$MUTEX_SLEEP_HISTORY :显示mutex sleep的最后单个事件,基于一个最详细的循环缓冲区
2、Mutex等待及含义
2.1、cursor: mutex S
我们尝试在共享模式下获得父游标或V$SQLSTAT桶上的互斥锁。
互斥锁处于"变化中"(有人正在以共享模式获取它),所以我们必须等到持有者完成它的共享获取。
如何使用:
•检查父游标,查询V$SQLSTATS桶。
2.2、cursor: mutex X
我们尝试在独占模式下获得父游标或V$SQLSTAT桶上的mutex,有人已经在不兼容模式下持有该mutex,或者有人已经在X模式下持有mutex,或者在S模式下可能有多个持有者。
如何使用:
在父游标下加载新的子游标,修改V$SQLSTATS桶,更新绑定捕获数据。
2.3、cursor: pin S
我们尝试将游标固定在共享模式(例如用于执行)。
子游标固定的mutex是"在变化中",有人已经在固定同一个游标了。
我们必须等到其他会话完成他们的pin请求。
2.4、cursor: pin X
我们尝试在独占模式pin一个游标,但有人已经在不兼容模式将其pin。
或者一个session已经在X模式pin该游标,或者多个session在S模式pin该游标。
2.5、cursor: pin S wait on X
我们尝试在共享模式下pin一个游标,但是有人已经在X模式下pin该游标。其他会话当前正在加载该子游标(解析)。
在11g中,大多数库缓存latch都直接被库缓存哈希桶上的mutex所取代。
每个哈希桶都由一个单独的mutex保护
2.6、library cache: mutex S
试图在S模式下获得库缓存哈希桶上的mutex
mutex已经保持在不兼容模式或处于"in flux "
2.7、library cache: mutex X
试图在X模式下获得库缓存哈希桶上的mutex
mutex已经处于不相容的模式或处于"in flux "
3、查看mutex相关的等待事件解释
SQL> select NAME,PARAMETER1,PARAMETER2,PARAMETER3,WAIT_CLASS from v$event_name where PARAMETER1='idn';
NAME PARAMETER1 PARAMETER2 PARAMETER3 WAIT_CLASS
------------------------------ ---------- ---------- -------------------- --------------------
cursor: mutex X idn value where|sleeps Concurrency
cursor: mutex S idn value where|sleeps Concurrency
cursor: pin S wait on X idn value where|sleeps Concurrency
library cache: mutex X idn value where Concurrency
library cache: mutex S idn value where Concurrency
cursor: pin X idn value where|sleeps Other
cursor: pin S idn value where|sleeps Other
7 rows selected
SQL>
与任何等待事件一样,参数(P1、P2、P3)提供了关于等待的额外细节和上下文信息
Parameter1 (idn)可用于查找与互斥锁相关的游标
Parameter2 (value)可用于查找以独占模式持有mutex的会话
对于所有共享模式持有者,都需要系统状态转储
3.1、PARAMETER1 - idn
cursor:* 等待事件
idn = 受保护的库缓存对象的哈希值
library cache: mutex* 等待事件
(1)库缓存哈希桶号 (if idn <= 131072)
(2) idn = 受保护的库缓存对象的哈希值 (if idn >131072)
通过hash_value 查找SQL
SELECT sql_text FROM v$sql WHERE hash_value = &idn;
通过库缓存桶查找SQL(idn <= 131072):
SELECT sql_text FROM v$sql WHERE MOD(hash_value, 131072) = &idn;
从AWR中通过SQL_ID查找SQL (hash_value is the lower half of SQLID):
SELECT sql_text FROM dba_hist_sqlstat
WHERE tpt.sqlid_to_sqlhash( sql_id ) = &idn;
3.2、PARAMETER2 - value
low bytes of word (2 or 4 bytes) - number of mutex shared references
high bytes of word (2 or 4 bytes) - SID of exclusive holder
SQL> select session_id, event, blocking_session,
2 to_char(p2, '0XXXXXXX') value_hex
3 from v$active_session_history
4 where event like 'library cache: mutex%';
SESSION_ID EVENT BLOCKING_SESSION VALUE_HEX
---------- --------------------------- ---------------- ---------
157 library cache: mutex X 00830000
3.3、PARAMETER 3 - where
where = maps to x$mutex_sleep.location_id
有助于理解从哪个内核函数中执行MUTEX 的get操作 ,用于高级诊断。
4、mutex的根因
在正常情况下,mutex等待意味着高并发性。
当环境强制非顺序执行时,更有可能发生mutex等待的问题。
这是CPU超额分配的问题,迫使进程随机休眠。
一个简单的公式来确定您的机器是否被超额分配CPU:
(total) AAS > # CPU cores
所以100%的CPU使用率不是CPU的最佳使用。
在我遇到的大多数latch和mutex问题中,最终证明是CPU超额分配放大了互斥锁等待