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中鎖的實現機制,我會在另外一篇文章中說明。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章