Curosr相关的Mutex等待事件(转)

转自:http://blog.chinaunix.net/uid-20785090-id-4675808.html

  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待以后再讨论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值