全部博文(389)
分类: Oracle
2014-12-05 20:05:12
Curosr相关的Mutex等待事件
从oracle官方手册关于mutex的定义来看,mutex是一个低级别的锁机制,用来保护SGA中
的共享对,像防止被老化出去.
A mutual exclusion object (mutex) is a low-level mechanism that prevents an object in memory from aging
out or from being corrupted when accessed by concurrent processes. A mutex is similar to a latch,
but whereas a latch typically protects a group of objects, a mutex protects a single object
---来自12C的concept
但是这里面有几个内容:究竟什么是低级别?保护SGA中的什么内容?
在现有的版本中muext主要有以下几个等待事件:cursor:pin S, cursor:pin X,cursor:mutex S;cursor:mutex X
cursor:pin S wait X,library cahce:mutex X, library cache:mutex S.
Mutex本身有可能是和被保护对像在一起,也可能是一个单独的位置.
首先我们来看SQL的处理过程,又是从官档上摘下的内容,当一个服务器进程接收到一个SQL后,会在
共享池中进行查找,如果没查找,就会做一个hard parse,那hard parse又做了一些什么事呢?
When an application issues a SQL statement, the application makes a parse call to the database
to prepare the statement for execution. The parse call opens or creates a cursor, which is a handle for
the session-specific private SQL area that holds a parsed SQL statement and other processing information
general stages of SQL processing: parsing, optimization, row source generation, and execution. Depending
on the statement, the database may omit some of these steps
---来自12C的concept
根据官档说的,会进行语法分析,语义分析,然后进行优化,生成执行计划.这一系列的最终成果在共享
池中反映就是生成一个SQL Cursor。
这个Cursor又可以分为两部分,一个是Parse Cursor,一个Child Cursor.Parse Cursor存放的是sql文
本的信息,而Child Cursor存放的是动态信息,比如环境变量,优化器设置和执行计划等等.当另一个相同的
相同SQL的发布时, Parse Cursor可以被共享,但是Child Cursor不一定能被共享.
当第一次SQL生成一个Parent和Child的时候,会等待cursor:pin X来保护自己请求的对像结构,防
止另一个会话做相同的事.当试图在一个Parent Cursor下构建Child Cursor时会在Parent上请求一个
Mutex X时,产生等待事件cursor: mutex X.
通过在两个不同的会话分别执行以下sql,假设cursor_sharing 为exact.
会话1
declare
i int;
j int;
begin
while (true)
loop
i:=i+1;
select i into j from dual;
end loop;
end;
会话2
declare
i int;
j int;
begin
while (true)
loop
i:=i+1.1;
select i into j from dual;
end loop;
end;
可以观察到很频繁的cursor:mutex X的等待.
SQL> select sid,event from v$session_wait
2 where wait_class<>'Idle'
3 /
SID EVENT
---------- ----------------------------------------------------------------
207 cursor: mutex X
582 cursor: mutex X
在开始的时候会对Parent cursor进行一个检查,会在该Parent cursor上的Mutex上等待,该等待事件
是cursor:mutex X.当发现系统中cursor:mutex X过高时,请检查AWR中的Hard Parse和平常是不是有很大变化.
当要真正执行一个语句时,在共享池中的形式是Cursor,这个时候需要把Cursor Pin住。以防止Cursor
被老化出去.主要的等待事件就是cursor:pin S.但是
会话1
declare
i int;
j int;
begin
while (true)
loop
i:=i+1;
select i into j from dual;
end loop;
end;
会话2
declare
i int;
j int;
begin
while (true)
loop
i:=i+1; --与前例此处不同
select i into j from dual;
end loop;
end;
摸拟两个话同时反复执行相同的语句,这时候可以观察到很频繁的cursor:pin S等待.
SQL> select sid,event from v$session_wait
2 where wait_class<>'Idle'
3 /
SID EVENT
---------- ----------------------------------------------------------------
207 cursor: pin S
582 cursor: pin S
cursor:pin S是只读方式去获得mutex,只是需要去更改一个ref的值,所以也形成争用.我们知道
ref就是内存中一个地址,可以看出更快的cpu和内存总线会得到速度更快哦.即使单个会话本身也
会去在这个事件上等等.相比硬件在很多时候无法改变了,只有去优化热的对像.比如人为的打散
sql语句.
第一个会话
declare
i int;
j int;
begin
while (true)
loop
i:=i+1;
select /*+ a */ i into j from dual; --修改这里
end loop;
end;
/
第二个会话
declare
i int;
j int;
begin
while (true)
loop
i:=i+1;
select /*+ b */ i into j from dual; --修改这里
end loop;
end;
/
SQL> run;
SID EVENT
---------- ----------------------------------------------------------------
207 latch: shared pool
582 latch: shared pool
产生大量的latch争用了,看来真是一波平另一波起.
AWR中mutex出现在top 5事件中的常见原因的有:硬解过多;high version count;oracle bug,
shared pool过小等
另外还有两个library cache的mutex待以后再讨论