RAC 鎖管理與鎖問題的定位(二)

vage發表於2012-03-28
RAC 鎖管理與鎖問題的定位(二)

在上一篇中(http://space.itpub.net/321157/viewspace-718009),我們講述了RAC下鎖的管理模式。本篇中,我們總結下出現鎖問題後的定位。有上節的基礎,你會發現在RAC下查詢鎖問題,是如此的簡單。
我們這次以TX鎖為例,TX鎖的競爭最為常見。我們的語句:
update t3 set id=id+0 where id=3;
我在兩個節點執行如下語句,肯定會被HANG住一個。下面,我們來說一下RAC下鎖問題處理的一般步驟。
一、查詢資源名
在被HANG住的節點中執行如下語句,查詢請求模式為6、鎖型別為TX的行:
 select * from v$lock where type='TX' and REQUEST=6;
ADDR     KADDR           SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
320CBB30 320CBB44        193 TX    1048616        291          0          6       1410          0
其實,我們要找的,是正在等待的TX鎖的資源名:TX-1048616-291,化成16進位制,TX-100028-123。變成V$DLM_RESS、V$GES_ENQUEUE檢視中的格式:
[0x100028][0x123],[TX]。
下面這條語句,直接輸出資源名:
SQL> select '[0x'||lower(trim(to_char(id1,'xxxxxxxx')))||'][0x'||lower(trim(to_char(id2,'xxxxxxxx')))||'],['||type||']'  from v$lock where
type='TX' and REQUEST=6;
'[0X'||LOWER(TRIM(TO_CHAR(ID1,'
-------------------------------
[0x100028][0x123],[TX]

二、定位主節點
找到資源名後,就可以在V$DLM_RESS中,以資源名為條件,查詢此資源的主節點:
SQL> select RESOURCE_NAME, ON_CONVERT_Q,ON_GRANT_Q, MASTER_NODE from V$DLM_RESS where resource_name like '[0x100028][0x123],[TX]%';
RESOURCE_NAME                  ON_CONVERT_Q ON_GRANT_Q MASTER_NODE
------------------------------ ------------ ---------- -----------
[0x100028][0x123],[TX]                    1          0           1
此資源的主節點是1,也就是第二個節點。上面兩條語句,還可以合在一起:
select RESOURCE_NAME, ON_CONVERT_Q,ON_GRANT_Q, MASTER_NODE from V$DLM_RESS where resource_name like (select '[0x'||lower(trim(to_char
(id1,'xxxxxxxx')))||'][0x'||lower(trim(to_char(id2,'xxxxxxxx')))||'],['||type||']'  from v$lock where type='TX' and REQUEST=6)||'%';
三、定位持有鎖的節點
仍在審請鎖被阻塞的節點,查詢GV$GES_ENQUEUE檢視,語句如下:
col STATE for a10
select inst_id,GRANT_LEVEL, REQUEST_LEVEL,PID, OWNER_NODE,WHICH_QUEUE,STATE,BLOCKED,BLOCKER from GV$GES_ENQUEUE where  resource_name1 like
(select '[0x'||lower(trim(to_char(id1,'xxxxxxxx')))||'][0x'||lower(trim(to_char(id2,'xxxxxxxx')))||'],['||type||']'  from v$lock where
type='TX' and REQUEST=6)||'%';
結果如下:
   INST_ID GRANT_LEV REQUEST_L        PID OWNER_NODE WHICH_QUEUE STATE         BLOCKED    BLOCKER
---------- --------- --------- ---------- ---------- ----------- ---------- ---------- ----------
         1 KJUSERNL  KJUSEREX        5527          0           2 OPENING             1          0
         2 KJUSEREX  KJUSEREX        6668          1           1 GRANTED             0          1         2 KJUSERNL  KJUSEREX           0          0           2 GRANTED             0          0
資源的主節點是第二個節點,只看INST_ID為2的行就行,例子中第二行,GRANT_LEVEL列為KJUSEREX,說明此行對應的程式,持有獨佔鎖,程式號為6668。但這
個程式號對我們沒有意義,因為此處程式永遠都是LMD。此處對我們有意義的列是OWNER_NODE,本例中為1。也就是第二個節點持有此鎖。
四、定位持有鎖的會話
我們已經找到是第二節點中某個會話持有鎖,接下來,查詢v$lock,就可以定位到會話號:
SQL> select * from v$lock where type='TX' and id1=1048616 and id2=291;
ADDR     KADDR           SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
30AA38E4 30AA3A00        192 TX    1048616        291          6          0       6791          2
192號會話持有的TX鎖,阻塞了另一個節點的Update語句。
有了這個會話號,我們可以查詢192執行的SQL、當前的等待事件等等,這就和單例項的一樣了,我就不再說了。

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

相關文章