标签: oracle call 函数   oracle statpack  

转自: http://blog.51cto.com/458302/998775

  Oracle的内部函数一直非常神秘,其实Oracle提供了一个oradebug 工具,可以用于调用内部的一些方法/函数,这为我们窥探Oracle的内部机制打开了一扇窗户。

    比如: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 ?

相关阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。