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. JS中如何操作数组

    背景:随笔中所应用到的代码来自于上一篇随笔,MVC&JQuery如何根据List动态生成表格,部分代码不再重复. 代码如下: $("#btnTan").click(func ...

  2. HTTP认证之基本认证——Basic(二)

    导航 HTTP认证之基本认证--Basic(一) HTTP认证之基本认证--Basic(二) HTTP认证之摘要认证--Digest(一) HTTP认证之摘要认证--Digest(二) 在HTTP认证 ...

  3. CodeForces 567F DP Mausoleum

    本着只贴代码不写分析的题解是在耍流氓的原则,还是决定写点分析. 思路很清晰,参考的官方题解,一下文字仅对题解做一个简要翻译. 题意: 有1~n这n个数,每个数用两次.构成一个长为2n的序列,而且要求序 ...

  4. 深度学习:Sigmoid函数与损失函数求导

    1.sigmoid函数 ​ sigmoid函数,也就是s型曲线函数,如下: 函数: 导数: ​ 上面是我们常见的形式,虽然知道这样的形式,也知道计算流程,不够感觉并不太直观,下面来分析一下. 1.1 ...

  5. PHP中define()和const定义常量的区别

    在PHP中可以通过define()和const两种方式定义常量可是在开发中我们应该什么时候用define()定义常量,什么时候用const定义常量? 这两种方式定义常量的主要区别是什么? 从5.3版本 ...

  6. [git 学习篇] --创建git创库

    http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013743256916071d ...

  7. [python IO学习篇]补充打开中文路径的文件

    http://blog.csdn.net/mottolinux/article/details/525600621 关于Python编码的基本常识 在python里面 “明文”是unicode类型和s ...

  8. IO Streams:字节流

    简介 程序使用字节流来执行8位字节的输入和输出.所有字节流类都继承于InputStream和OutputStream. 有很多字节流类:为了说明字节流如何工作,我们将重点关注文件I / O字节流Fil ...

  9. 《人月神话》读书笔记(2)-week3

    为了确保团队中的每个人都能保持系统概念上的完整性,关于项目的书面规格说明是必不可少的.手册要描绘用户可见的一切,但不应支配实现的过程.光有规格说明也是不够的,会议也是必要的.书中提到的周例会会迅捷地给 ...

  10. POJ 1323 Game Prediction

    Game Prediction Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8956   Accepted: 4269 D ...