如何阅读Oracle Errorstack Output(二)

2014-11-24 15:01:37 · 作者: · 浏览: 3
0000000000000001 0018A3F03 000000000 00601C7E0
如果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来发现匿名块的文本信息。
www.2cto.com
以上的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 /
[html]
LINE TEXT
---- -------------------------------------------------------------------
1 function delete_func (owner_name in varchar2) return number
2 as
3 num_deleted number;
4 begin
5 -- this is a demo procedure
6 -- it does not do anything useful!
7
8 DELETE FROM mytab WHERE owner = owner_name;
9 COMMIT;
10
11 num_deleted := SQL%ROWCOUNT;
12 DBMS_OUTPUT.PUT_LINE('Deleted rows ='|| TO_CHAR(num_deleted));
13
14 return num_deleted;
15 end; www.2cto.com
s selected.
你可以发现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,你就错了(它仅仅随机的采样绑定变量值,并不存储所有的被使用的绑定变量值).
Oracle 11gR2中实时的SQL Monitoring特性能够大道此目的。在V$SQL_MONITOR中有一列BIND_XML,此列包含正在运行的足够长时间(默认占用CPU超过5s的SQL,都会出现在次视图中)的bind variable values.但是这个只有在11gR2并且具有Diag+Tuning pack licenses时才有效。
为什么我们不能跟踪到绑定变量值的原因在于绑定变量值存在于进程的private memory。所以我们不能很容易的跟踪另一个进程private memory。这也是为什么我们使用ORADEBUG连接到出现问题的进程并且发出信号,使得它dump errorstack。很幸运的dump tracefile中包含CURSORDUMP,包含bind variable value。
注:关于V$SQL_MONITOR,我写过一篇blog,参见:V$SQL_MONITOR
下面的例子中,数字8213是我们将要dump的问题session的OS PROCESS ID(V$PROCESS.SPID):
SQL> oradebug setospid 8213
Oracle pid: 15, Unix process pid: 8213, image: oracleSOL102@solaris02
SQL> oradebug dump errorstack 3
Statement processed.
当然,如果你诊断CRASH或者ORA-600(错误已经发生,dump file已经存在)你肯定不需要使用ORADEBUG。继续看看如下dump:
[html]
*** 2010-02-14 15:30:32.830
ksedmp: internal or fatal error
Curr