• Oracle Mutex实现机制


    我们都知道Latch是Oracle用来在内存中做串行控制的机构,从10g R2开始,Oracle引入了一个新的技术-Mutex。Mutex并不是Oracle的发明,而是系统提供的一个底层调用,Oracle只是利用它实现串行控制的功能,并替换部分Latch。

    Mutex中有两个变量:分别是Holider identifer和Reference count,Holider identifer记录持有mutex的SID,而Reference count是一个计数,记录了当前正在以share方式访问mutex的数量,每当session以share方式持有mutex时,计数会加1,而释放时会减1。如果Reference count大于零,则表示该内存结构正在被Oracle pin住。

    我们看一段伪代码,演示mutex的申请过程:

    Function Mutex_get(mutex_name)
    {
      if mutex.holder:=SID
        case mode:
        'exclusive':
          if mutex.ref_count=0
            return TRUE
          else
            mutex.holder.clear;
            reture FALSE
          end if
        'share':
          mutex.ref_count++
          mutex.holder.clear
          return TRUE
        end case
      else
        reture FALSE
      end if
    }

    Mutex是如何实现串行控制的,实际上它是利用了操作系统的一个原子操作CAS(compare-and-swap)实现的。我们看到函数的开始处:mutex.holder:=SID,将SID赋值给mutex的Holider Identifer,这里就是一个原子的CAS操作,首先比较mutex.holder是否为空,如果不为空则赋值session的SID。CAS操作由OS来保证其原子性,在同一时刻这个操所是串行的。如果这个赋值操作失败,整个申请过程失败。赋值成功后,如果是share方式,则mutex.ref_count加1,并清空mutex.holder,如果是exclusive方式,需要判断mutex.ref_count是否为零(是否被pin住),如果大于0,则失败,并清空mutex.holder,如果等于0,则成功,这时不清空mutex.holder,保持当前session对mutex的exclusive占用,直到释放为止。

    Mutex相比latch带来了以下的好处:

    1.更少的资源消耗,mutex与latch不同,它不是独立存在的,而是在每个内存结构中,并随着内存结构创建和释放,mutex同时也被创建和释放。mutex暂用的空间比latch小很多,创建和释放消耗更少的资源。

    2.有效降低竞争,因为mutex是每个内存结构中的一部分,这样意味着mutex的数量可以有很多,而不同于latch,一个latch需要管理很多个内存结构,当你访问同一latch管理的不同内存结构时,也会发生竞争,而mutex则不会。另外,因为latch的数量有限,很多时候latch本身的竞争会很厉害,之前,我们只能增加latch数量或者减少latch持有的时间,而现在,mutex是一个更好的选择。

    3.更快的pin,当block被访问时,它必须被pin在buffer cache中,当一个cursor执行时,它也必须被pin在library cache中,如果大量并发频繁执行同一个cursor,library cache pin会耗费大量的CPU资源。而mutex使用reference count来解决并发访问的问题,只要它大于零,就表示它已经被pin在了内存中,不能被交换出去。而且mutex.ref_count++这个操所是非常快的,只占用非常少的资源。

    Mutex申请的过程和latch类似,同样需要spin和sleep,不同的是Oracle硬编码了mutex spin的次数为255次(Latch spin的次数默认为2000,由隐含参数_spin_count控制)。latch sleep会随着等待次数的逐步增加,每次sleep的时间也会逐步增加。而mutex sleep则比较特别,它有三个选项,分别是yield CPU,sleep或者block other process,允许开发人员来决定采用哪种选项。

    由于在某些RISC的操作系统中(HP-UNIX),由于系统不支持CAS操作,Oracle通过创建一个latch pool来模拟了CAS操作,被称为KGX latch,如果你发现系统中存在这种latch竞争,说明操作系统不支持CAS操作,可以通过_kks_use_mutex_pin关闭mutex。

    mutex主要使用在library cache中,用来取代原来的library cache pin和library cache lock,关于library cache中锁的实现机制,我会在另外一篇文章中说明。

    –EOF–

    注:有关CAS,可以参考wiki上的说明。

    引自:http://www.hellodb.net/2010/06/oracle-mutex.html

    1. 6 17th, 201020:48
      回复 | 引用 | #1
       

      在Oracle中, Mutex是一个类似于Lock的机制, 与Latch还是有较大的差异, Mutex有锁资源管理, 只是更加轻量级, latch类似于OS的spin_lock机制, 基本的操作类似于Compare and swap (或者Test and Set), 只是在内存中由Oracle进行控制(本人估计可能是为了避免进行过多的Kernel mode/user Mode的切换).

       
    2. 6 17th, 201022:18
      回复 | 引用 | #2
       

      latch是oracle自己实现的,mutex则是OS的系统调用,CAS的原子性是OS提供的,Oracle利用了它的特性。

       
    3. 6 19th, 201019:01
      回复 | 引用 | #3
       

      lock是一个排队机制,MUTEX应该还是和latch的机制差不多,只不过他更加轻量级,并且是通过资源本身上的count标志位来确定能否互斥,oracle的TX lock虽然也是用一个bit位来确定资源是否锁定,但是他需要维护排队信息,还是需要额外的resource的

       
    4. jacky
      6 19th, 201023:25
      回复 | 引用 | #4
       

      mutex是更轻量级的latch,而lock是由enqueue实现的,而enqueue这个结构又是靠latch保护起来的:)

       
    5. 6 21st, 201014:25
      回复 | 引用 | #5
       

      确实记错了啊.. 不过Mutex是os的系统调用吗?

       
    6. logchild
      6 21st, 201018:02
      回复 | 引用 | #6
       

      mutex在innodb中也大有所用

       
    7. jacky
      6 22nd, 201017:34
      回复 | 引用 | #7
       

      准确点说,mutex不是系统调用,而是用系统调用实现的,CAS在很多OS上都有现成的系统调用,由OS来保证其原子性。

       
    8. 7 3rd, 201022:42
      回复 | 引用 | #8
       

      Mutex是操作系统为了实现PV操作提供的原子功能,P/V两个操作都必须是原子的,才能保证并发不被打乱,与其相似的还有信号量Semaphore,这些都是操作系统原理上的东西了

  • 相关阅读:
    8088汇编跳转和PSW状态字寄存器
    Delphi的函数指针
    服务器系统及软件常见漏洞
    TGraphiControl响应WM_MOUSEMOVE的过程(以TPaintBox为例)good
    两个奇怪的取地址符号
    把x指针指向的4个字节次序颠倒过来
    DELPHI中的消息处理机制(三种消息处理方法的比较,如何截断消息)
    探索C++的底层机制
    setprecision、fixed、showpoint的用法总结(经典!!超经典!!)
    段寄存器和8种地址寻址方式
  • 原文地址:https://www.cnblogs.com/taowang2016/p/3118829.html
Copyright © 2020-2023  润新知