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 ?

Oracle内部latch获取函数简介的更多相关文章

  1. Delphi 版本信息获取函数 GetFileVersionInfo、GetFileVersionInfoSize、VerFindFile、VerInstallFile和VerQueryValue

    一.版本信息获取函数简介和作用 获取文件版本信息的作用: 1. 避免在新版本的组件上安装旧版本的相同组件: 2. 在多语言系统环境中,操作系统根据文件版本信息里提供的语言信息在启动程序时决定使用的正确 ...

  2. [转帖学习]Oracle的 SYS_CONTEXT 函数简介

    Oracle的 SYS_CONTEXT 函数简介 https://blog.csdn.net/IndexMan/article/details/48606369 1.什么是SYS_CONTEXT? S ...

  3. Linux Shell系列教程之(十五) Shell函数简介

    本文是Linux Shell系列教程的第(十五)篇,更多Linux Shell教程请看:Linux Shell系列教程 函数可以将一个复杂功能划分成若干模块,从而使程序结构更加清晰,代码重复利用率更高 ...

  4. PCRE函数简介和使用示例【转】

    PCRE函数简介和使用示例 标签: 正则表达式listbuffercompilationnullperl 原文地址:http://blog.csdn.net/sulliy/article/detail ...

  5. linux进程编程:子进程创建及执行函数简介

    linux进程编程:子进程创建及执行函数简介 子进程创建及执行函数有三个: (1)fork();(2)exec();(3)system();    下面分别做详细介绍.(1)fork()    函数定 ...

  6. [转]SQLITE3 C语言接口 API 函数简介

    SQLITE3 C语言接口 API 函数简介 说明:本说明文档属作者从接触 SQLite 开始认识的 API 函数的使用方法, 由本人翻译, 不断更新. /* 2012-05-25 */ int sq ...

  7. Oracle中的单行函数

    Oracle中的单行函数 1 字符函数 UPPER()--将字符串转换为大写 SELECT UPPER('abc') FROM dual; LOWER()-将字符串转换为小写 SELECT LOWER ...

  8. 创建类似于Oracle中decode的函数

    -- 创建类似于Oracle中decode的函数create or replace function decode(variadic p_decode_list text[])returns text ...

  9. UNIX网络编程——epoll 系列函数简介、与select、poll 的区别

    前面博客<<UNIX环境高级编程--epoll函数使用详解>>有关于epoll函数的讲解. 一.epoll 系列函数简介 #include <sys/epoll.h> ...

随机推荐

  1. German Collegiate Programming Contest 2015

    // Legacy Code #include <iostream> #include <cstdio> #include <cstring> #include & ...

  2. 一个JS判断客户端是否已安装某个字体(Only IE)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. Oracle 表空间的日常维护与管理

    目录 Oracle 表空间的日常维护与管理 1.创建数据表空间 2.创建临时表空间 3.创建 UNDO 表空间 4.表空间的扩展与修改大小 5.表空间重命名 6.表空间的删除 7.更改表空间的读写模式 ...

  4. 到底有没有必要兼容IE版本

    我就说两个字:"没有". 理由如下: 1.占资源空间,额外去写css hack去做页面兼容处理.(主要是增加css代码) PS:css hack 不是W3C的规范,css hack ...

  5. 算法理论——PLA

    全称 perceptron learning algrithm 用武之地 二值分类问题,资料线性可分 算法核心(以二维平面为例) 找到一条直线WTX=0,一边全为+1,另一边全为-1.找到了这条线(即 ...

  6. [python工具篇][pycharm安装与配置][1]安装与设置

    1 官网下载专业版 2 打开pycharm,选择license server 激活,地址输入:http://idea.imsxm.com 3 新建工程(一个大文件夹) 4 设置字体大小(file-&g ...

  7. JAVA调用oracle存储过程实例

    1.创建添加存储过程 CREATEORREPLACEPROCEDURE stu_proc(v_id INNUMBER, v_name INVARCHAR2, v_age INNUMBER) AS BE ...

  8. java EE技术体系——CLF平台API开发注意事项(1)——后端开发

    前言:这是一篇帮助小伙伴在本次项目中快速进入到java EE开发的一些说明,为了让同组小伙伴们开发的时候,有个清晰点的思路.昨天给大家演示分享了基本概况,但没有留下文字总结说明,预防后期有人再次问我, ...

  9. WTForms 表单动态验证

    class UserDetails(Form): group_id = SelectField(u'Group', coerce=int) def edit_user(request, id): us ...

  10. vue.js源码学习分享(二)

    /** * Check if value is primitive//检查该值是否是个原始值 */ function isPrimitive (value) { return typeof value ...