Wirte By tanelpoder,translation by me.
当Oracle发生关键的错误诸如:ora-600,Errorstack dump是自动被oracle dump。当你在alert.log里面看见错误,将产生trace文件,trace中以“ksedmp:internal or fatal
error”开头,诸如这样的错误(ORA-7445或者ORA-600附有一些参数)。”kesdmp”意味着Kernel Service Error Dump,所以此行下面的就是errorstack dump。
Errorstack dump也可以被手动的调用通过使用Oradebug errorstack 3(当使用Oradebug setospid设定了目标进程之后)。Oradebug Errorstack对于当一个session似乎Hang(
但是在v$session_wait里面并未出现合理的wait event)或者是比正常时消耗更多资源并且你想知道当前sql的具体变量值。
Errorstack trace文件有很多信息,对于我们troubleshooting或多或少都有用。但是大量的数据和二进制的转储可能使你摸不着头脑,这里我将给你展示可以理解的一些结构。
在这片文章里我们将探讨以下话题:
1.从errorstack trace file中发现当前正在执行SQL文本。
2.从errorstack trace file中发现当前正在执行PL/SQL package和PL/SQL source code line number。
3.从errorstack trace file中发现当前bind variable value。
4.从errorstack trace file中发现一个cursor正在使用多少private memory(UGA)。
我将在下面的阐述中粘贴一个errorstack dump的相关部分。
1.从errorstack trace file中发现当前正在执行SQL文本。
你将非常容易找到当前sql的文本信息,这个语句在tracefile的前端(“Current SQL statement for this session”)部分:
2.从errorstack trace file中发现当前正在执行PL/SQL package和PL/SQL source code line number。
如果dump的tracefile中这个进程是一个PL/SQL调用,那么PL/SQL调用堆也被dump(在PL/SQL Call Stack部分)。这部分告诉你当错误发生时Oracle在执行那个PL/SQL过程以及
dump的时候过程中的那个调用发生错误。
PL/SQL call stack报告3列:
1.object handle
object handle是这个对象(PL/SQL存储过程或者匿名块)被load进library cache中的地址。你可以通过映射这个地址通过X$KGLOB.KGLHDADR以发现那个对象是正在被处理。
然而对象的owner和name是在第三列被报告。
2.line number
这个是非常重要的信息,它将告诉你当errorstack dump发生时正在执行的精确的PL/SQL source code。例如,在如上的输出中,这个匿名块调用了SYS.DELETE_FUNC在第一行(
匿名块的第一行)。当errorstack dump发生时正在执行SYS.DELETE_FUNC的PL/SQL source code的第八行。
3.object name
PL/SQL存储的对象名(或者匿名块,当对象并没有存储在一个过程中).当是匿名块的情况下(匿名块的文本可以通过V$SQL发现),你可以关联这个地址和V$SQL.ADDRESS来发现匿名块的文本信息。
以上的PL/SQL call stack仅仅包含两行。
38d172270 8 function SYS.DELETE_FUNC
38d1518f0 1 anonymous block
你应该从下而上来阅读一个PL/SQL call stack:
1.底部的行可以告诉我们正在执行一个匿名块以及在这个匿名块的第一行,它在调用这个函数(SYS.DELETE_FUNC)。
2.顶部信息告诉我们SYS.DELETE_FUNC是正在执行,在第八行导致了错误,,errorstack信息被转储。
通过查询DBA_SOURCE,我们可以从dump和行号等信息中发现这个对象的owner和name。
SQL> select line, text
2 from dba_source
3 where owner = ‘SYS’
4 and name = ‘DELETE_FUNC’
5 — and line between X and Y
6 and type = ‘FUNCTION’ — PROCEDURE,PACKAGE BODY,TYPE BODY
7 order by line asc
8 /
你可以发现dump中正在执行的PL/SQL第八行(递归的DELETE查询).
通常,当error dump,crash,hang发生时(顶部的行是”parent”function调用的“child”function正在执行的代码),PL/SQL errorstack告诉我们精确的PL/SQL code。
3.从errorstack trace file中发现当前bind variable value
这个问题是经常被问的,让我来这样回答:
1.一个session可能一某种方式变的非常消耗CPU,并且没有任何有意义的wait event.
2.所以你需要调查什么SQL正在被执行并且你需要查看SQL带有的绑定变量.
3.SQL的执行计划是正常的,但是性能却机器糟糕。
4.可以假设当某些表或者行源变的大的时候,存在数据倾斜,CBO没有计算出正确的执行计划。
所以,你需要知道当问题发生时SQL使用的绑定变量是什么,不幸的是并没有一个V$视图让我们去查看某个session的当前绑定变量值。如果你考虑使用V$SQL_BIND_CAPTURE,你就错了(它仅仅随机的采样绑定变量值,并不存储所有的被使用的绑定变量值).