oracle mutex
瞭解 Oracle Mutex
雖然Mutex中文翻譯為互斥鎖,但為了和OS mutex充分的區別,所以我們在本文裡稱Oracle Mutex為Mutex。
Oracle中的mutex,類似於Latch,是一種低階的序列機制,用以控制對SGA中部分共享資料結構的訪問控制。 Oracle中的序列機制有不少,引入它們的目的是避免一個物件出現下述現象:
-
當某些程式在訪問該物件時,該資源被重新分配
-
當某些程式在修改它時,被其他程式讀取
-
當某些程式在修改它時,被其他程式修改
-
當某些程式在讀取它時,被其他程式修改
-
哪些需要被mutex保護的共享資料結構可以有自己獨立的mutex,即一個物件擁有自己獨立的mutex,不像Latch往往一個需要保護大量物件,舉例來說,每一個父遊標有其對應的mutex, 而每一個子遊標也有其對應的mutex
-
每一個資料結構可能有一個或多個mutex保護,每一個mutex負責保護其結構的不同部分
-
當然一個mutex也可以用來保護多於一個的資料結構
-
基於發生的不同操作,對應不同的等待事件:
-
在某個父遊標名下建立一個新的遊標 ==> 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 *’的形式
-
傳統的’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 *’的形式
-
在某個父遊標下構建一個新的子游標
-
首先這種構建新子游標的操作更廉價了, 當時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 。
-
ordered by number of sleeps desc
-
Cursor Stat (kgx_kks1)
-
Cursor Parent (kgx_kks2)
-
Cursor Pin (kgx_kks3)
-
某程式以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上。
-
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 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 持有了。
不同於Latch,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的操作:
針對遊標統計資訊的操作
Mutex是如何替代library cache pin來保護cursor heap的?
KKS使用MUTEX情況下SQL語句的 解析與執行的收益
在版本10.2中, 以下是幾個SQL解析與執行從MUTEX哪裡獲得主要收益:
查詢SQL統計資訊
透過V$SQLSTAT檢視(本質上是X$KKSSQLSTAT)訪問SQL統計資訊時,其所需要的CPu和獲取的Latch數量要遠遠少於訪問其他V$SQL檢視。 在早期版本中, 並行地訪問V$SQL或者V$SQLAREA檢視會造成 library cache latch的爭用。
下面是一個AWR中的Mutex Sleep Statistics, 這些資料主要來源於V$MUTEX_SLEEP檢視。
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種:
在版本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的過程:
Mutex相關的等待事件
cursor: mutex * events等待事件
‘cursor: pin * events’等待事件
該類等待事件一般是為了pin相關的子游標
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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle:cursor:mutex XOracleMutex
- [20220301]oracle如何定位使用library cache mutex.txtOracleMutex
- [20220302]oracle如何定位使用library cache mutex 2.txtOracleMutex
- [20220303]oracle如何定位使用library cache mutex 3.txtOracleMutex
- 【轉】spin lock 和mutexMutex
- 當 Go struct 遇上 MutexGoStructMutex
- [20190402]Library Cache mutex.txtMutex
- Go 系列教程 —— 25. MutexGoMutex
- pthread_mutex 鎖問題threadMutex
- spinlock和mutex選用方法Mutex
- [20210903]探究mutex的值.txtMutex
- golang開發:CSP-WaitGroup MutexGolangAIMutex
- Go語言的互斥鎖MutexGoMutex
- [譯] part25: golang Mutex互斥鎖GolangMutex
- 原始碼剖析 golang 中 sync.Mutex原始碼GolangMutex
- Go 併發程式設計之 MutexGo程式設計Mutex
- 互斥鎖mutex的簡單實現Mutex
- Go 互斥鎖 Mutex 原始碼分析(二)GoMutex原始碼
- golang 中 sync.Mutex 的實現GolangMutex
- Go死鎖——當Channel遇上Mutex時GoMutex
- [20210915]探究mutex的值 6.txtMutex
- [20210914]探究mutex的值 4.txtMutex
- [20210914]探究mutex的值 5.txtMutex
- Go併發程式設計--Mutex/RWMutexGo程式設計Mutex
- [20210916]探究mutex的值 8.txtMutex
- Go 標準庫 —— sync.Mutex 互斥鎖GoMutex
- Cursor Mutex S Waits等待事件引發hangMutexAI事件
- 【Go進階—併發程式設計】MutexGo程式設計Mutex
- [20201203]探究library cache mutex X 3.txtMutex
- go中sync.Mutex原始碼解讀GoMutex原始碼
- [20190401]隱含引數_mutex_spin_count.txtMutex
- mutex,latch,lock,enqueue hash chains latch基礎概念MutexENQAI
- 純Mutex實現多執行緒交替列印Mutex執行緒
- 11g parallel_instance_group 'cursor: mutex S'ParallelMutex
- GO: sync.Mutex 的實現與演進GoMutex
- C# 中的 Mutex(互斥體)基礎用法C#Mutex
- golang pprof監控系列(2) —— memory,block,mutex 使用GolangBloCMutex
- golang中的Mutex設計原理詳解(一)GolangMutex
- C#多執行緒(4):程式同步Mutex類C#執行緒Mutex