oracle mutex

murkey發表於2014-06-24

瞭解 Oracle Mutex

  雖然Mutex中文翻譯為互斥鎖,但為了和OS mutex充分的區別,所以我們在本文裡稱Oracle Mutex為Mutex。

  Oracle中的mutex,類似於Latch,是一種低階的序列機制,用以控制對SGA中部分共享資料結構的訪問控制。 Oracle中的序列機制有不少,引入它們的目的是避免一個物件出現下述現象:

  •   當某些程式在訪問該物件時,該資源被重新分配

  •   當某些程式在修改它時,被其他程式讀取

  •   當某些程式在修改它時,被其他程式修改

  •   當某些程式在讀取它時,被其他程式修改

  •   不同於Latch,Mutex的使用更靈活,用途更多,例如:

  •   哪些需要被mutex保護的共享資料結構可以有自己獨立的mutex,即一個物件擁有自己獨立的mutex,不像Latch往往一個需要保護大量物件,舉例來說,每一個父遊標有其對應的mutex, 而每一個子遊標也有其對應的mutex

  •   每一個資料結構可能有一個或多個mutex保護,每一個mutex負責保護其結構的不同部分

  •   當然一個mutex也可以用來保護多於一個的資料結構

  •   理論上mutex即可以存放在其保護的結構本身中(其實是嵌入在結構裡),也可以存放在其他地方。 一般情況下Mutex是在資料結構需要被保護時動態建立出來的。 如是嵌在需要保護結構體內的mutex,則當 所依附的資料結構被清理時 該mutex也將被摧毀。

      雖然mutex和latch都是Oracle中的序列機制,但是mutex具有一些latch沒有的好處

    更輕量級且更快

      Mutex作為Latch的替代品,具有更快速獲得,更小等優勢。 獲取一個mutex進需要大約30~35個指令, 而Latch則需要150~200個指令。一個mutex結構的大小大約為16 bytes,而在10.2版本中一個latch需要112個bytes,在更早的版本中是200個bytes。 從200個bytes 精簡到112個是透過減少不必要的統計指標 SLEEP1~SLEEP11、WAITERS_WOKEN, WAITS_HOLDING_LATCH等從而實現的。今後我們將看到更多關於Latch的程式碼最佳化。

    減少偽爭用

      典型情況下一個Latch保護多個物件。 當一個Latch保護多個熱物件時,並行地對這些物件的頻繁訪問讓latch本身變成效能的序列點。 這也就是我們此處說的偽爭用點, 因為爭用是發生在這個序列保護的機制上,而不是程式去訪問的物件本身。與latch不同, 使用mutex的情況下Oracle開發人員可以為每一個要保護的資料結構建立一個獨立的mutex。 這意味著Latch的那種偽爭用將大大減少,因為每一個物件均被自己獨立擁有的mutex保護

      一個Mutex可供多個Oracle程式並行地參考,反過來說程式們可以以S(Shared 共享) mode模式參考一個Mutex。以S mode一起共享參考這個mutex的程式的總數成為參考總數reference count。Mutex自身結構中存放了這個ref count的資料。另一方面,mutex也可以被以X (Exclusive)mode排他模式被僅有一個程式所持有Held。

      Mutex有2種用途,一方面他們可以充當維護必要序列機制的結構,如同latch那樣; 同時也可以充當pin,避免物件被age out。

      舉例來說,mutex結構中包含的ref count資訊可以用作替代library cache pin。 在mutex充當cursor pin之前,當一個程式要執行=>pin一個cursor時需要做的是針對性地建立library cache pin和刪除這個library cache pin(均為S mode)。mutex充當cursor pin之後,程式只需要增加和減少mutex上的ref count即可。

      當某一個程式首次解析一個遊標 Cursor,他將臨時建立並移除一個library cache pin,但是該程式後續的解析或執行進要求增加或者減少ref count。注意在這個增加/減少ref count的過程中無需acquire latch,這是因為mutex自身能起到限制序列訪問修改ref count的作用。 當一個程式要移除自己的mutex pin時,它減少ref count,同樣的無需acquire 任何latch。

    Mutex和Latch的互動

      Latches和Mutex 是獨立的序列機制, 舉例來說一個程式可以同時持有latch和mutex。 在程式異常dead的情況下,一般latch要比Mutex更早被PMON清理。 一般情況下不存在mutex的死鎖。 不像latch,在早期版本例如9i之前我們經常遇到latch死鎖的問題。

    Mutex的用途

      在版本10.2中僅僅有 KKS 這個核心層是mutex的客戶,KKS 意為 Kernel Kompile Shared, 它是Library Cache中的shared cursor遊標共享部分層次的程式碼。 在之後的版本中,ORACLE開發部門更多地使用了Mutex,不侷限於KKS。

    KKS遊標共享如何使用Mutex

      kks 使用mutex以便保護對於下述基於parent cursor父遊標和子游標child cursor的一系列操作。

    對於父遊標parent cursor的操作:

  •   基於發生的不同操作,對應不同的等待事件:

  •   在某個父遊標名下建立一個新的遊標 ==> cursor:mutex X

  •   檢查一個父遊標 ==> cursor:mutex S

  •   繫結值捕獲 ==> cursor:mutex X

  •   保護父遊標的mutex嵌入在父遊標結構內

  •   針對父遊標parent cursor的Mutex型別為’Cursor Parent’ (kgx_kks2).

  •   針對父遊標parent cursor的Mutex等待事件均為’ Cursor: mutex *’的形式

  • 針對遊標統計資訊的操作

  •   基於對不同的遊標統計資訊的操作有不同的等待事件:

  •   構造,更新遊標相關的統計資訊 ==> cursor:mutex X

  •   檢測遊標相關的統計資訊,例如訪問V$SQLSTATS ==> cursor : mutex S

  •   相關的遊標可能在父遊標中,也可能在遊標統計資訊相關的hash table上

  •   針對遊標統計資訊的Mutex型別為Cursor Stat (kgx_kks1)

  •   針對遊標統計資訊的Mutex等待事件均為’ Cursor: mutex *’的形式

  • Mutex是如何替代library cache pin來保護cursor heap的?

  •   傳統的’library cache pin’在10.2.0.2之後預設被取代, 此處PIN被Mutex及其ref count取代。 當程式執行遊標語句時或者需要PIN,或者需要hard parse一個子遊標heap。

  •   在版本10.2.0.1中, 使用mutex部分程式碼替代PIN的功能預設是不啟用的,實際上這取決於隱藏引數_KKS_USE_MUTEX_PIN,在10.2.0.2之後_KKS_USE_MUTEX_PIN預設為TRUE。 換而言之在版本10.2中我們還是可以關閉KKS使用MUTEX替代PIN保護CURSOR的, 但是在版本11g中則幾乎無法關閉MUTEX。 注意10.2中僅當KKS真正使用MUTEX時,library cache pin不再用作cursor pin。

  •   基於對不同的遊標統計資訊的操作有不同的等待事件:

  •   為執行某個SQL而PIN一個遊標Cursor ==>Cursor: Pin S Wait on X

  •   當執行一個遊標而PIN Cursor,而該Cursor正被其他程式以S mode檢測 ==> cursor:pin S

  •   當試圖重建一個遊標Cursor ==> Cursor: pin X 該等待事件一般不太會看到,因為當一個遊標正被執行,且其需要重建時會有另一個遊標被建立

  •   保護遊標的mutex嵌入在遊標結構內

  •   Mutex型別為’Cursor Pin’ (kgx_kks3)

  •   等待事件均為 ‘cursor: pin *’的形式

  • KKS使用MUTEX情況下SQL語句的 解析與執行的收益

      在版本10.2中, 以下是幾個SQL解析與執行從MUTEX哪裡獲得主要收益:

  •   在某個父遊標下構建一個新的子游標

  •   首先這種構建新子游標的操作更廉價了, 當時Maclean仍要告誡你 一個父遊標下過多的子游標仍不是一件好事情

  •   對父遊標的檢測

  •   在找到一個合適的遊標並執行前,父遊標需要被適當檢測。 對父遊標的這種檢測目前也使用mutex來保護了,所以這種檢測更的成本更低了

  •   對於已經載入在Library Cache 中的SQL語句重複執行

  •   常規情況下,當一個程式要執行SQL遊標前總是必須要先pin它

  •   不使用MUTEX的情況:若遊標處於OPEN狀態下以便今後的重複執行,且引數cursor_space_for_time(CSFT 目前已不推薦使用該引數)為TRUE,則每一次重複執行可以不需要library cache pin。 若遊標處於OPEN狀態下但是cursor_space_for_time=false,則程式在重複執行SQL遊標前總是要先拿library cache pin

  •   使用MUTEX的情況: 相反,若使用mutex來替代library cache pin時,則無需關心cursor_space_for_time 。 僅第一個程式需要做一個PIN,其他後續程式都只需要簡單地在對應保護cursor heap的mutex上拿一個共享reference 。

  • 查詢SQL統計資訊

      透過V$SQLSTAT檢視(本質上是X$KKSSQLSTAT)訪問SQL統計資訊時,其所需要的CPu和獲取的Latch數量要遠遠少於訪問其他V$SQL檢視。 在早期版本中, 並行地訪問V$SQL或者V$SQLAREA檢視會造成 library cache latch的爭用。

      下面是一個AWR中的Mutex Sleep Statistics, 這些資料主要來源於V$MUTEX_SLEEP檢視。

  •   ordered by number of sleeps desc

  • Mutex Type Location Sleeps Wait Time (ms)
    Library Cache kglhdgh1 64 2,356 0
    Library Cache kglpnal2 91 2,345 0
    Cursor Pin kkslce [KKSCHLPIN2] 2,084 0
    Library Cache kglpin1 4 956 0
    Library Cache kglhdgn2 106 784 0
    Library Cache kglpndl1 95 691 0
    Library Cache kglpnal1 90 605 0
    Library Cache kgllkdl1 85 580 0
    Library Cache kgllkal1 80 404 0
    Library Cache kglllal3 111 282 0
    Library Cache kglllal1 109 218 0
    Library Cache kglhdgn1 62 163 0
    Library Cache kgllldl2 112 156 0
    Library Cache kgllkc1 57 105 0
    Library Cache kglget2 2 100 0
    Library Cache kglini1 32 53 0
    Library Cache kglget1 1 31 0
    Cursor Pin kksLockDelete [KKSCHLPIN6] 22 0
    Library Cache kgllkal3 82 18 0
    Library Cache kglUnsetHandleReference 120 10 0
    Cursor Pin kksxsccmp [KKSCHLPIN5] 10 0
    Library Cache kglobld1 75 8 0
    Cursor Pin kksfbc [KKSCHLPIN1] 8 0
    Library Cache kglUpgradeLock 119 7 0
    Library Cache kglhdgc1 102 2 0
    Cursor Pin kksfbc [KKSCHLFSP2] 2 0
    Library Cache kgldtin1 42 1 0
    Library Cache kglhbh1 63 1 0
    Library Cache kgllkal5 84 1 0
    Library Cache kglrdtin1 44 1 0
    Cursor Parent kkscsPruneChild [KKSPRTLOC35] 1 0

      Mutex的型別Mutex Type

      Mutex的型別其實就是 mutex對應的客戶的名字, 在版本10.2中基本只有KKS使用Mutex,所以僅有3種:

  •   Cursor Stat (kgx_kks1)

  •   Cursor Parent (kgx_kks2)

  •   Cursor Pin (kgx_kks3)

  •   在版本11g中擴充套件了對Mutex的使用,在Library Cache的HASH BUCKET中嵌入了mutex以保護hash bucket,所以多了一種mutex type : Library Cache

      哪些程式碼函式會申請Mutex?

      Oracle中哪些程式碼函式會申請Mutex? 例如KKSFBC等,其實很像 V$LATCH的location列

      10.2中最常見的下面的幾個函式

      kkspsc0 -負責解析遊標 - 檢測我們正在解析的遊標是否有物件的parent cursor heap 0存在

      kksfbc - 負責找到合適的子游標 或者建立一個新的子游標

      kksFindCursorstat

      11g開始有大量函式需要用到Mutex了

      SQL> select location from X$MUTEX_SLEEP_HISTORY;

      LOCATION

      —————————————-

      kkslce [KKSCHLPIN2]

      kksfbc [KKSCHLFSP2]

      kglhdgn2 106

      kglpin1 4

      kglhdgn2 106

      kglllal1 109

      kglpin1 4

      kglpndl1 95

      kglpin1 4

      kglpin1 4

      kksfbc [KKSCHLFSP2]

      kglhdgn1 62

      kglpnal1 90

      kglllal3 111

      kglpnal1 90

      kglpnal1 90

      kglget2 2

      kglllal3 111

      kglget2 2

      kglobld1 75

      kkslce [KKSCHLPIN2]

      kglpndl1 95

      kglpndl1 95

      kglpin1 4

      kkslce [KKSCHLPIN2]

      kglpin1 4

      kglget2 2

      kglllal1 109

      kgllkc1 57

      kglget2 2

      kglpnal1 90

      kglpin1 4

      kglpin1 4

      kglpin1 4

      kgllkdl1 85

      kglllal3 111

      kgllldl2 112

      kglpin1 4

      kglpndl1 95

      kkslce [KKSCHLPIN2]

      kksLockDelete [KKSCHLPIN6]

      kglpndl1 95

      kkslce [KKSCHLPIN2]

      kglpnal1 90

      kglpin1 4

      kglpin1 4

      kgllldl2 112

      kgllkdl1 85

      kglpin1 4

      kglhdgn2 106

      kglhdgn2 106

      kksLockDelete [KKSCHLPIN6]

      kglhdgn1 62

    Mutex的Get和Sleep

      當一個Mutex被申請時, 一般稱為一個get request。 若初始的申請未能得到授權, 則該程式會因為此次申請而進入到255次SPIN中(255是在程式碼中用常量寫死的),每次SPIN迴圈迭代過程中該程式都會去看看Mutex被釋放了嗎。

      若該Mutex在SPIN之後仍未被釋放,則該程式針對申請的mutex進入對應的mutex wait等待事件中。 實際程式的等待事件和等待方式由mutex的型別鎖決定,例如 Cursor pin、Cursor Parent。 舉例來說,這種等待可能是阻塞等待,也可以是sleep。

      但是請注意在V$MUTEX_SLEEP_*檢視上的sleep列意味著等待的次數。相關程式碼函式在開始進入等待時自加這個sleep欄位。

      等待計時從程式進入等待前開始計算等待時間, 當一個程式結束其等待,則等待的時間加入都總和total中。 該程式再次嘗試申請之前的Mutex,若該Mutex仍不可用,則它再次進入spin/wait的迴圈。

      V$MUTEX_SLEEP_HISTORY檢視的GETS列僅在成功申請到一個Mutex時才增加。

      短期持有一個mutex: spin 迴圈255次一般可以有效以S mode獲得一個mutex, 前提是該Mutex 已經被以S mode持有。 簡單來說若有2個程式同時以S mode去申請一個Mutex,則稍晚的一個申請者需要進入SPIN並等稍早一點的申請者完成它的例如建立針對該mutex的一個reference的操作,但這都是非常迅速的操作。

      長期持有一個Mutex: 如若一個Mutex已經被某程式以X mode持有, 則往往有其程式以SHRD模式去申請該mutex時仍發現該mutex 以X mode被其他程式所持有,則往往這個EXCL 持有是 LONG_EXCL(可以透過SSD DUMP發現),則後續的申請者往往要進入spin迴圈,甚至需要等待

      上面我講了willing-to-wait的mutex, 實際上mutex 的申請也可以是 nowait的。程式以nowait申請mutex時不會進入spin-cycle也不sleep,它只繼續常規處理。 當一個nowait get失敗時,將增加一次miss,但是實際上V$MUTEX_SLEEP_*中記錄的miss不是這樣的miss, 檢視中記錄的miss是等待的次數, 對於真正的miss沒有統計項。

      Wait Time等待時間

      類似於latch,spin time 不算做mutex的消耗時間,它只包含等待消耗的時間。

    真正理解Mutex相關的等待

      Mutex資料結構中存放了Holder id持有者ID , Ref Count,和其他Mutex相關的統計資訊。 Holder id對應於持有該Mutex的session id (v$session.sid) 。 特別注意, Ref Count是程式併發以S mode參考該Mutex的程式數量(如下文的演示)。

      當一個Mutex被以X mode 持有,則Holder id 為對應持有該mutex的session id,而Ref Count為0。

      每一個共享S mode持有者僅僅增加mutex上的Ref Count。 可供大量session併發以S mode持有參考一個Mutex。 但是注意更新ref count的操作是序列的, 這是為了避免錯漏並維護mutex中正確的ref count。

      下面我們詳細介紹一個執行遊標過程中對mutex share pin的過程:

  •   某程式以SHRD 模式申請一個Mutex,並嘗試臨時修改該Mutex的Holder ID

  •   若該Mutex正被他人更新,則該session會將Holder id設定為本session的sid,之後該程式將增加ref count,之後再清楚mutex上的Holder id。簡單來說 這個Holder id是真正做了並行控制的功能。 若該Holder id 被設定了,則說明該Mutex要麼被以EXCL模式持有,要麼正有一個其他程式在以S mode申請該Mutex的過程中(例如更新Ref Count)。 當更新Ref Count時臨時設定holder id的目的就是為了實現避免其他程式併發更新該Mutex的機制。 透過這些例子說明了 , Mutex既可以用作Latch併發控制, 也可用作pin。

  •   若Holder id已被設定,則申請程式將可能進入等待事件 。 例如若當前Mutex的持有者程式正以X mode更新該Mutex,則申請者的等待事件應為”cursor: pin S on X” 。 而若當持有者Holder並不是”真的要持有” 該Mutex,而僅僅是嘗試更新其Ref Count,則第二個程式將等在’ Cursor :pin S’等待事件上; 實際正在更新Ref count的操作時很快的,是一種輕微的操作。 當第一個程式正在更新mutex,則後續的申請程式將進入spin 迴圈中255次等待前者結束。 當mutex上不再有 Holder id時(如前者的程式已經更新完Ref Count)時, 則申請者程式將Holder ID設為自身的SID,並更新Ref Count,並清除Holder id。 若在255次迴圈SPIN後mutex仍不被釋放,則該程式進入等待並不再跑在CPU上。

  • Mutex相關的等待事件

      cursor: mutex * events等待事件

  •   cursor: mutex * events等待事件用於Cursor Parent 和 Cursor stats型別的操作:

  •   ‘cursor: mutex X’ , 某個程式申請以EXCL mode持有mutex時進入該等待, 該Mutex要麼正被其他程式以SHRD模式參考,這導致X mode的申請必須要等待直到Ref count=0, 或者該mutex正被另一個程式以X mode持有。

  •   相關操作要求以EXCL X mode持有Mutex的:

  •   在一個父遊標下建立一個新的子游標

  •   捕獲SQL中的繫結變數

  •   更新或構件SQL統計資訊V$SQLSTATS

  •   ‘Cursor: Mutex S’ , 某個程式以SHRD S mode申請一個Mutex, 而該Mutex要麼被其他程式已EXCL X mode所持有,要麼其他程式正在更新mutex 上的Ref Count。

  •   相關型別的操作一般是檢測父遊標或者CURSOR統計資訊資料, 此外查詢V$SQLSTATS也會造成CURSOR statistics被查詢

  •   ‘cursor: pin * events’等待事件

      該類等待事件一般是為了pin相關的子游標

  •   cursor: pin S 當一個程式以共享pin模式申請一個Mutex,而不能立即獲得時,進入cursor: Pin S等待事件。 Mutex Pin是以共享型別的操作,例如執行一個遊標。

  •   當一個程式等在cursor: pin S上,說明該程式在對一個共享的mutex pin 參考或取消參考時,有其他的程式也正在為同樣的cursor heap建立或者取消一個共享Mutex pin。 實際上cursor: pin S 等待事件應當很少見,因為更新共享Mutex pin 的reference 應當是很快的。 再重複一次,S mode的Mutex可以被併發持有, 但是更新Mutex的Ref Count仍需要序列地處理 。 一旦reference count被增加好,則後續程式將可以為同樣的cursor heap增加reference count。 因此此處mutex 即可以扮演Latch的角色(序列控制ref count的更新),又可以扮演pin的角色(ref count本身)。

  •   ‘cursor: pin X’ 當一個程式需要以EXCL X mode獲得mutex時, 這類需要EXCL X 模式的序列操作包括:

  •   構建一個子遊標

  •   某個程式已經以X mode持有該Mutex

  •   一個或多個程式正在reference 該Mutex (shared mutex pin)

  •   ‘Cursor: pin S on X’ 最常見的等待事件, 程式為了共享操作例如執行pin遊標而以SHRD S mode申請mutex, 但是未立即獲得。原因是該遊標被其他程式以EXCL X mode 持有了。

  • Mutex的相關統計檢視

      V$MUTEX_SLEEP

      shows the wait time, and the number of sleeps for each combination of mutex type and location.

      V$MUTEX_SLEEP_HISTORY

      displays time-series data. Each row in this view is for a specific time, mutex type, location, requesting session and blocking session combination. That is, it shows data related to a specific session (requesting session) that slept while requesting a specific mutex type and location, because it was being held by a specific blocking session. The data in this view is contained within a circular buffer, with the most recent sleeps shown.

      接著我們會在環境中模擬cursor pin S wait on X的場景,並透過systemstate dump和v$mutex_sleep , v$mutex_sleep_history等檢視觀察這一現象

      session A:

      SQL> select * from v$version;

      BANNER

      —————————————————————-

      Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi

      PL/SQL Release 10.2.0.5.0 - Production

      CORE 10.2.0.5.0 Production

      TNS for Linux: Version 10.2.0.5.0 - Production

      NLSRTL Version 10.2.0.5.0 - Production

      

      SQL> show parameter kks

      SQL>

      SQL> create table mac_kks tablespace users nologging as select * from dba_objects;

      Table created.

      SQL> insert /*+ append */ into mac_kks select * from mac_kks;

      77386 rows created.

      SQL> commit;

      Commit complete.

      SQL> insert /*+ append */ into mac_kks select * from mac_kks;

      154772 rows created.

      SQL> commit;

      Commit complete.

      SQL> insert /*+ append */ into mac_kks select * from mac_kks;

      309544 rows created.

      SQL> commit;

      Commit complete.

      SQL> insert /*+ append */ into mac_kks select * from mac_kks;

      619088 rows created.

      SQL> commit;

      Commit complete.

      SQL> insert /*+ append */ into mac_kks select * from mac_kks;

      1238176 rows created.

      SQL> commit;

      Commit complete.

      SQL> oradebug setmypid

      Statement processed.

      SQL> oradebug tracefile_name

      Statement processed.

      SQL> alter table mac_kks add t2 char(2000) default ‘MACLEAN’;

      session B:

      SQL> oradebug setospid 32424

      Oracle pid: 17, Unix process pid: 32424, image: oracle@vrh8.oracle.com (TNS V1-V3)

      SQL> oradebug suspend;

      Statement processed.

      session C:

      select * from mac_kks where rownum=1; ==> hang

      session D:

      select * from mac_kks where rownum=1; ==> hang

      session E:

      SQL> select sid,event from v$session where wait_class!=’Idle’;

      SID EVENT

      ———- —————————————————————-

      141 SQL*Net message to client

      145 library cache lock

      149 cursor: pin S wait on X

      159 log buffer space

      SQL> oradebug setmypid

      Statement processed.

      SQL> oradebug dump systemstate 266;

      Statement processed.

      SQL> oradebug tracefile_name

      /s01/admin/G10R25/udump/g10r25_ora_32537.trc

      Object Names

      ~~~~~~~~~~~~

      LOCK: handle=a7115ef0

      Mutex 7fff7abadecf

      KGX Atomic Operation Log 0x8d88a8d8

      Mutex 0x954eaff8(145, 0) idn 7fff7abadecf oper EXCL

      Cursor Pin uid 145 efd 0 whr 1 slp 0

      opr=3 pso=0x97951af0 flg=0

      pcs=0x954eaff8 nxt=(nil) flg=35 cld=0 hd=0xa7864b08 par=0x9523a9e0

      ct=0 hsh=0 unp=(nil) unn=0 hvl=9595c3d8 nhv=1 ses=0xa8416738

      hep=0x954eb078 flg=80 ld=1 ob=0x95ac6128 ptr=0x8fd90128 fex=0x8fd8f438

      0x954eaff8(145, 0) ==> sid和 ref count

      pso ==> parent state object

      hd=0xa7864b08 ==>cursor 對應的handle address

      par ==> 父遊標的heap 0 pointer

      ses=0xa8416738 ==》 一般 EXCL是才有 session address v$session.saddr

      SID=145 對Mutex 0x954eaff8 oper EXCL以X mode Hold 該Mutex, SID=145 在等 SYS.MAC_KKS表的library cache lock,該表被X mode pin和lock,而解析SQL要求以S mode lock該表

      SID=149 對Mutex 0x954eaff8 申請 oper GET_SHRD, SID=149在等cursor: pin S wait on X

      KGX Atomic Operation Log 0x8db79798

      Mutex 0x954eaff8(145, 0) idn 7fff7abadecf oper GET_SHRD

      Cursor Pin uid 149 efd 0 whr 5 slp 13893

      opr=2 pso=0x8e6bd518 flg=0

      pcs=0x954eaff8 nxt=(nil) flg=35 cld=0 hd=0xa7864b08 par=0x9523a9e0

      ct=0 hsh=0 unp=(nil) unn=0 hvl=9595c3d8 nhv=1 ses=0xa8416738

      hep=0x954eb078 flg=80 ld=1 ob=0x95ac6128 ptr=0x8fd90128 fex=0x8fd8f438

      SO: 0xa841bd18, type: 4, owner: 0xa830cf98, flag: INIT/-/-/0×00

      (session) sid: 149 trans: (nil), creator: 0xa830cf98, flag: (80000041) USR/- BSY/-/-/-/-/-

      DID: 0001-0019-00000066, short-term DID: 0000-0000-00000000

      txn branch: (nil)

      oct: 0, prv: 0, sql: 0x8d88bf90, psql: (nil), user: 0/SYS

      service name: SYS$USERS

      O/S info: user: oracle, term: pts/5, ospid: 32510, machine: vrh8.oracle.com

      program: sqlplus@vrh8.oracle.com (TNS V1-V3)

      application name: sqlplus@vrh8.oracle.com (TNS V1-V3), hash value=543908804

      waiting for ‘cursor: pin S wait on X’ wait_time=0, seconds since wait started=0

      idn=7abadecf, value=9100000000, where|sleeps=500003645

      blocking sess=0x(nil) seq=13901

      Dumping Session Wait History

      for ‘cursor: pin S wait on X’ count=1 wait_time=0.266596 sec

      idn=7abadecf, value=9100000000, where|sleeps=500003644

      for ‘cursor: pin S wait on X’ count=1 wait_time=0.010679 sec

      idn=7abadecf, value=9100000000, where|sleeps=500003643

      for ‘cursor: pin S wait on X’ count=1 wait_time=0.010633 sec

      idn=7abadecf, value=9100000000, where|sleeps=500003642

      for ‘cursor: pin S wait on X’ count=1 wait_time=0.010843 sec

      idn=7abadecf, value=9100000000, where|sleeps=500003641

      for ‘cursor: pin S wait on X’ count=1 wait_time=0.011008 sec

      idn=7abadecf, value=9100000000, where|sleeps=500003640

      for ‘cursor: pin S wait on X’ count=1 wait_time=0.010406 sec

      SO: 0xa8416738, type: 4, owner: 0xa830bfa8, flag: INIT/-/-/0×00

      (session) sid: 145 trans: (nil), creator: 0xa830bfa8, flag: (80000041) USR/- BSY/-/-/-/-/-

      DID: 0001-0017-0000008E, short-term DID: 0000-0000-00000000

      txn branch: (nil)

      oct: 3, prv: 0, sql: 0x8d88bf90, psql: (nil), user: 0/SYS

      service name: SYS$USERS

      O/S info: user: oracle, term: pts/4, ospid: 32485, machine: vrh8.oracle.com

      program: sqlplus@vrh8.oracle.com (TNS V1-V3)

      application name: sqlplus@vrh8.oracle.com (TNS V1-V3), hash value=543908804

      waiting for ‘library cache lock’ wait_time=0, seconds since wait started=165

      handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

      blocking sess=0x(nil) seq=9

      Dumping Session Wait History

      for ‘library cache lock’ count=1 wait_time=3.297287 sec

      handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

      for ‘library cache lock’ count=1 wait_time=2.930321 sec

      handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

      for ‘library cache lock’ count=1 wait_time=2.930856 sec

      handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

      for ‘library cache lock’ count=1 wait_time=2.930698 sec

      handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

      for ‘library cache lock’ count=1 wait_time=2.931518 sec

      handle address=a7115ef0, lock address=978def20, 100*mode+namespace=c9

      SO: 0x978def20, type: 53, owner: 0xa8456058, flag: INIT/-/-/0×00

      LIBRARY OBJECT LOCK: lock=978def20 handle=a7115ef0 request=S

      call pin=(nil) session pin=(nil) hpc=0005 hlc=0000

      htl=0x978defa0[0x8e4a8950,0x8e4a8950] htb=0x8e4a8950 ssga=0x8e4a7a88

      user=a8416738 session=a8416738 count=0 flags=RES/[0010] savepoint=0x1f

      LIBRARY OBJECT HANDLE: handle=a7115ef0 mtx=0xa7116020(0) lct=8 pct=10 cdp=0

      name=SYS.MAC_KKS

      hash=c066b9b9c6c80736a15f5ba325563fdb timestamp=04-14-2013 00:43:14

      namespace=TABL flags=KGHP/TIM/SML/[02000000]

      kkkk-dddd-llll=0000-0701-0201 lock=X pin=X latch#=3 hpc=0006 hlc=0004

      lwt=0xa7115f98[0x978def50,0x978def50] ltm=0xa7115fa8[0xa7115fa8,0xa7115fa8]

      pwt=0xa7115f60[0xa7115f60,0xa7115f60] ptm=0xa7115f70[0xa7115f70,0xa7115f70]

      ref=0xa7115fc8[0xa7115fc8,0xa7115fc8] lnd=0xa7115fe0[0x9cc2c260,0xa79fd198]

      LIBRARY OBJECT: object=95f0e5b0

      type=TABL flags=EXS/LOC/UPD[0905] pflags=[0000] status=VALD load=0

      DATA BLOCKS:

      data# heap pointer status pins change whr

      —- ——- ——- ——— —- —— —

      0 a78d3840 95f0e708 I/P/A/-/- 0 NONE 00

      8 957a6ad8 94461f88 I/P/A/-/- 1 UPDATE 00

      Mutex 0x954eaff8 被 SID=145 oper EXCL以X mode Hold 該Mutex

      體現為 子游標child cursor被以 X mode pin

      SO: 0x8e6bd518, type: 53, owner: 0xa841bd18, flag: INIT/-/-/0×00

      LIBRARY OBJECT LOCK: lock=8e6bd518 handle=a7864b08 mode=N

      call pin=(nil) session pin=(nil) hpc=0000 hlc=0000

      htl=0x8e6bd598[0x8e542f60,0x979da4d0] htb=0x979da4d0 ssga=0x979d96c8

      user=a841bd18 session=a841bd18 count=1 flags=CBK[0020] savepoint=0×0

      LIBRARY OBJECT HANDLE: handle=a7864b08 mtx=0xa7864c38(0) lct=2 pct=3 cdp=0

      namespace=CRSR flags=RON/KGHP/PN0/EXP/[10010100]

      kkkk-dddd-llll=0000-0001-0001 lock=N pin=X latch#=3 hpc=0002 hlc=0002

      lwt=0xa7864bb0[0xa7864bb0,0xa7864bb0] ltm=0xa7864bc0[0xa7864bc0,0xa7864bc0]

      pwt=0xa7864b78[0xa7864b78,0xa7864b78] ptm=0xa7864b88[0xa7864b88,0xa7864b88]

      ref=0xa7864be0[0x954eb320,0x954eb320] lnd=0xa7864bf8[0xa7864bf8,0xa7864bf8]

      LIBRARY OBJECT: object=95ac6128

      type=CRSR flags=EXS[0001] pflags=[0000] status=VALD load=0

      DATA BLOCKS:

      data# heap pointer status pins change whr

      —- ——- ——- ——— —- —— —

      0 8d81aa70 95ac6240 I/P/A/-/- 0 NONE 00

      6 954eb0f0 8fd90128 I/P/A/-/E 0 NONE 00

      並行執行6個SQL語句 並做systemstate dump :

      [oracle@vrh8 ~]$ grep SHRD /s01/admin/G10R25/udump/g10r25_ora_32716.trc |grep 0×95987388

      Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

      Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

      Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

      Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

      Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

      Mutex 0×95987388(0, 6) idn 7fff8f32fff6 oper SHRD

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/500314/viewspace-1192396/,如需轉載,請註明出處,否則將追究法律責任。

相關文章