Oracle內部latch獲取函數簡介

  Oracle的內部函數一直很是神祕,其實Oracle提供了一個oradebug 工具,能夠用於調用內部的一些方法/函數,這爲咱們窺探Oracle的內部機制打開了一扇窗戶。web

    好比:Oracle內部獲取latch的函數爲kslgetl,全稱爲Kernel Service Lock Management Get Latch,能夠使用oradebug call kslgetl/kslfre命令來手動獲取一個latch,這種方法可用於模擬latch爭用相關的現象。

    kslgetl函數有四個參數,調用格式以下:

      kslgetl(laddr, wait, why, where) 
 參數說明以下:

 

  • laddress – latch在 SGA中的地址
  • wait – flag. 若是設置爲true,表示使用 willing-to-wait mode模式。
  • where –  請求latch的代碼段位置 ,也就是awr/statpack的Latch Misses Source中的內容。
  • why -   爲何從Where參數指定的地方請求latch
     注意where中的位置值只是一個索引,具體的位置名稱從v$latch_misses能夠查到(或者從awr/statspack也能夠看到)。代碼位置的名稱和索引存儲在視圖x$ksllw  
SQL> select indx, ksllwnam,ksllwlbl from x$ksllw where rownum<20;
 
      INDX KSLLWNAM                                                         KSLLWLBL
---------- ---------------------------------------------------------------- ----------------------------------------------------------------
         0 No latch
         1 kslwt
         2 ksudlp
         3 kslpstevent:get                                                  pwq#
         4 kslpstevent:reget                                                pwq#
         5 ksliwat:add:nowait                                               pwq#
         6 ksliwat:remove                                                   pwq#
         7 ksliwat:add:wait                                                 pwq#
         8 kslael
         9 kslrgpl_parent
        10 kslrgpl_2child
 
      INDX KSLLWNAM                                                         KSLLWLBL
---------- ---------------------------------------------------------------- ----------------------------------------------------------------
        11 kslrgpl_notsib
        12 kslrgp_nowait
        13 ksqgel: create enqueue                                           parent obj
        14 ksqgel: failed to get enqueue                                    error
    


      視圖v$latch_misses的基礎表是x$kslwsc,在這個表裏Oracle維護了一個latch丟失代碼位置的數組。x$kslwsc(猜想的名稱爲:kernel service where of source code),經過這個視圖,能夠找到latch對應的索引:
SQL> desc  x$kslwsc;
Name                                                                          Null?    Type
----------------------------------------------------------------------------- -------- ----------------------------------------------------
ADDR                                                                                   RAW(8)
INDX                                                                                   NUMBER
INST_ID                                                                                NUMBER
KSLNOWTF                                                                               NUMBER
KSLSLEEP                                                                               NUMBER
KSLWSCWSL                                                                              NUMBER
KSLWSCLTHG                                                                             NUMBER
KSLLASNAM                                                                              VARCHAR2(50)  

why參數的在dump出來的結果中描述是「Context saved from call」,例如:
SO: 0x2d93be720, type: 2, owner: (nil), flag: INIT/-/-/0x00
(process) Oracle pid=299, calls cur/top: 0x2e9028a38/0x2e9028a38, flag: (0)

(latch info) wait_event=0 bits=2
holding 2dee1ac50 Child cache buffers chains level=1 child#=124200
Location from where latch is held: kcbgtcr: fast path:
Context saved from call: 39022946
why參數說明爲何在這個(where)請求這個latch,它依賴於latch的做用與latch請求的where。好比,當請求一個cache buffer chain latch保護的一個數據塊時,why就包括一個塊地址(dba)。why的意義,能夠從x$ksllw中的ksllwlbl列進行一些猜想。
 
where與why參數用於獲取一個latch,當latch獲取成功後,Oracle保存參數的值到latch的結構中.Oracle 11g更進一步擴展了latch架構,存儲在x$kslltr_parent和x$kslltr_children視圖中,分別表示parent latch與children latch。10g或之前的版本,都是使用x$ksllt表,v$latch與v$latch_children都是以x$ksllt爲基表。   最近獲取latch的"Where"與"Why"的值能夠從這些表的kslltwhr與kslltwhy兩個表查詢到。
 
x$ksuprlat顯示持有latch的進程,他是v$latchholder的基表,where與why的值也在它的ksulawhr與ksulawhy列中。
 
     咱們來手動獲取一個latch試試看:
SQL> select addr, name from v$latch where name like 'shared pool';
 
ADDR             NAME
---------------- --------------------------------------------------
0000000380019DA8 shared pool
 
SQL> 

取這個latch的where值,也就是代碼位置:
SQL> select *  from x$kslwsc where ksllasnam ='shared pool';
 
ADDR                   INDX    INST_ID   KSLNOWTF   KSLSLEEP  KSLWSCWSL KSLWSCLTHG KSLLASNAM
---------------- ---------- ---------- ---------- ---------- ---------- ---------- ------------

............
     
00000005F7152178       2582          1          0          0          0          0 shared pool
00000005F7152198       2583          1          0          0          0          0 shared pool
00000005F71521B8       2584          1          0          0          0          0 shared pool
00000005F71521D8       2585          1          0          0          0          0 shared pool
 
62 rows selected

這些值也能夠從x$ksllt取到

SQL> select kslltwhr,kslltwhy from x$ksllt  where addr='0000000380019DA8';
 
  KSLLTWHR   KSLLTWHY
---------- ----------
      2559        208
 
SQL> 
 
 
如今咱們用oradebug手動執行kslgetl函數:
SQL> connect /as sysdba;
Connected.
SQL> oradebug setmypid;
Statement processed.
SQL>  oradebug   call   kslgetl   0 x380019DA8   1   208   2559
ORA-03113: end-of-file on communication channel
ORA-24323: value not allowed
 
    發現出錯了,查看trace文件,能夠看到出現了一個ora-007445   [Address not mapped to object]錯誤:
 
*** 2012-03-10 15:00:56.229
ksedmp: internal or fatal error
ORA-07445: exception encountered: core dump [kslgetl()+8] [SIGSEGV] [Address not mapped to object] [0xFFFFFFFF80021E44] [] []
----- Call Stack Trace -----
calling              call     entry                argument values in hex     
location             type     point                (? means dubious value)    
-------------------- -------- -------------------- ----------------------------
ksedmp()+728         CALL     ksedst()             000000017 ? 106B520AC ?
                                                   000000000 ? 106B4EBA0 ?
                                                   106B4D908 ? 106B4E308 ?
ssexhd()+1232        CALL     ksedmp()             106994000 ? 10699493C ?
                                                   000106800 ? 10699493C ?
                                                   000000000 ? 106994000 ?
__sighndlr()+12      PTR_CALL 0000000000000000     106991000 ? 106B55EF0 ?
                                                   10698E81C ? 000106991 ?
                                                   00000000B ? 000000067 ?
call_user_handler()  CALL     __sighndlr()         00000000B ? 106B55EF0 ?
+992                                               106B55C10 ? 102084BC0 ?
                                                   000000000 ? 00000000A ?
sigacthandler()+104  CALL     call_user_handler()  FFFFFFFF7D100200 ?
                                                   FFFFFFFF7D100200 ?
                                                   106B55C10 ? 000000009 ?
                                                   000000000 ? 000000000 ?
kslgetl()+8          PTR_CALL 0000000000000000     000000000 ? 106B55EF0 ?
                                                   106B55C10 ?
                                                   FFFFFFFF7D100200 ?
                                                   000000000 ?
                                                   FFFFFFFF7C33E000 ?
skdxcall()+1664      PTR_CALL 0000000000000000     FFFFFFFF80021E38 ?
                                                   000000001 ? 0000000D0 ?
                                                   0000009FF ?
                                                   FFFFFFFF7FFFABC0 ?
                                                   0000009FF ?
ksdxen()+3672        PTR_CALL 0000000000000000     380021E38 ?
                                                   FFFFFFFF7FFFB350 ?
                                                   FFFFFFFF7FFFB348 ?
                                                   FFFFFFFF7FFFB340 ?
                                                   FFFFFFFF7FFFB3F0 ?
                                                   FFFFFFFF7FFFB338 ?
opiodr()+1536        PTR_CALL 0000000000000000     105AB8000 ? 1020766C0 ?
                                                   10699294A ? 000105800 ?
                                                   000106800 ? 106991CA8 ?
ttcpip()+1188        PTR_CALL 0000000000000000     105AE96F0 ? 105E47870 ?
                                                   000106991 ? 106991000 ?
                                                   000000056 ? 000106800 ?
opitsk()+1532        CALL     ttcpip()             00000001E ? 000000000 ?
                                                   FFFFFFFF7FFFE5B8 ?
                                                   000000001 ?
                                                   FFFFFFFF7FFFD090 ?
                                                   10698F208 ?
opiino()+1128        CALL     opitsk()             000000000 ? 105E46B00 ?
                                                   000000000 ? 000100000 ?
                                                   105A9E49C ? 10699D160 ?
opiodr()+1536        PTR_CALL 0000000000000000     00010699B ? 000000000 ?
相關文章
相關標籤/搜索