Oracle数据库诊断事件详解[转帖从cooly老大的博客]

什么是Oracle数据库的诊断事件呢?简而言之的来说Oracle的诊断事件就是Oracle数据库中用于实现一些特殊功用的类别,一般主要用于实现以下几个方面的功用:

Ø 改变Oracle数据库的行为

Ø 启用收集Oracle数据库的跟踪或者调试信息

Ø 启用对Oracle数据库的额外的错误检测


一、 Oracle数据库诊断事件简介
什么是Oracle数据库的诊断事件呢?简而言之的来说Oracle的诊断事件就是Oracle数据库中用于实现一些特殊功用的类别,一般主要用于实现以下几个方面的功用:
Ø 改变Oracle数据库的行为
Ø 启用收集Oracle数据库的跟踪或者调试信息
Ø 启用对Oracle数据库的额外的错误检测

如何去设置Oracle数据库的各种诊断事件呢?我们首先来给设置诊断事件下一个简单的定义,就是让Oracle数据库产生跟踪信息日志文件。设置诊断事件有如下的四种方法:
Ø 在INIT或者SPFILE初始化文件中设置
这种设置的诊断事件都是针对于整个实例的:
event='event trace name context forever, level level';
如果需要设置多个诊断事件,可以通过以下两种方法:
方法一:使用冒号分隔开两个诊断事件
event = "10248 trace name context forever, level 10:10249 trace name context forever, level 10"
方法二:使用连续的行设置诊断事件
event = "10248 trace name context forever, level 10"
event = "10249 trace name context forever, level 10"
Ø 在当前SQL会话中设置
针对整个实例的诊断事件的设置:
ALTER SYSTEM SET EVENTS 'event trace name context forever, level level';
禁用设置的诊断事件:
ALTER SYSTEM SET EVENTS 'event trace name context off';
针对当前会话的诊断事件的设置:
ALTER SESSION SET EVENTS 'event trace name context forever, level level';
禁用设置的诊断事件:
ALTER SESSION SET EVENTS 'event trace name context off';
Ø 在另外一个SQL会话中使用DBMS_SYSTEM.SETEV存储过程设置
EXECUTE sys.dbms_system.set_ev(sid, serial#, , , '')
其中的SID,SERIAL#都是从视图V$SESSION中获得的。
Ø 在另外一个会话中使用debug工具设置
对一个进程设置诊断事件:
ORADEBUG EVENT event TRACE NAME CONTEXT FOREVER, LEVEL level
禁用设置的诊断事件:
ORADEBUG EVENT event TRACE NAME CONTEXT OFF
对一个会话设置诊断事件:
ORADEBUG SESSION_EVENT event TRACE NAME CONTEXT FOREVER, LEVEL level
禁用设置的诊断事件:
ORADEBUG SESSION_EVENT event TRACE NAME CONTEXT OFF

注:在Oracle8i以上的版本中,是使用sysdba权限的用户登陆sqlplus后执行ORADEBUG命令;在Oracle7.3/8.0的版本中,是使用internal用户登陆svrmgrl后执行ORADEBUG命令;在更早的Oracle版本中使用ORADBX (ORAMBX在VMS系统上)。因为oradebug允许在另外的会话中设置诊断事件,这样就可以跟踪一些平时不太trace的会话,例如对export工具的诊断。诊断事件可以分成会话级的诊断事件和进程级的诊断事件,进程级的诊断事件是可以在INIT初始化参数文件中设定,会话级的诊断事件则可以使用"alter session..."或者"alter system ..."命令来设定。Oracle数据库在检测诊断事件的时候都是先检测会话级的诊断事件,然后再检测进程级的诊断事件。

对于设置Oracle数据库的诊断事件都必须遵循一定的语法,例如在会话级别上设置诊断事件可以按照以下的语法来设置:
alter session set events '10181 trace name context forever, level 1000';
而同样的诊断事件在INIT初始化参数文件中就应该按照以下语法设置:
event="10181 trace name context forever, level 1000"
在INIT初始化参数文件中设置诊断事件的时候,一般来说最好在诊断事件后加上相关的注释,注释的内容一般来说应该包括诊断事件的作用、为什么要使用这个诊断事件以及设置诊断事件的时间。
下面这个图是关于设置诊断事件的语法表:

诊断事件规定的语法为:
{:}*
Event Name:它代表关联事件的符号名或者是一个事件号。如果是immediate,代表是一个立即无条件的诊断事件,不用去等待任何人发布它;也可以是指定的Oracle错误号码,还可以是具体的事件名。
Action:分为和。Action Key Word的值可以是trace、debugger、crash,而qualifiers的语法则是依赖于具体的Action。
Ø 当为crash的时候,语法为:
"" (默认为空)|"off" (在等待事件中禁用crash)| "aftertimes" (发生此事件N次后crash)
Ø 当为debugger的时候,语法为:
"" (默认为空)| "off" (在等待事件中禁用debugger)| "aftertimes" (发生此事件N次后debugger)| "forever" (一旦开始debugger,以后每次发生事件时都要debugger)| "lifetime " (一旦开始debugger,以后N次发生事件时都要debugger,然后在此诊断事件中禁用debugger)
Ø 当为trace的时候,语法为:
"name "{,}*
Trace Name:是关联内部trace号的符号名。其中,context是一种特殊的trace name,它不会去调用调试dump操作,但是却会返回给发起诊断事件者是否context跟踪被激活,跟踪是什么级别的。跟踪的级别是指dump程序内部使用来控制dump出来详细信息的级别,通常来说,级别越高,dump出来的信息就会越详细,最低级别是1。All是另外一种特殊的trace name,它意味着通过"ksdtradv"宏在编译的时候声明所有的trace names。如果在诊断事件中关联多余一个以上的trace,至少有一个应该是context,相应的,诊断事件中最后一个关联的动作将返回跟踪的级别,而且在不同的调用中诊断事件号最好唯一。
trace qualifier的语法为:
""(默认为空)|"off"(在等待事件中禁用这个trace)| "after times" (发生此事件N次后开始trace)|"forever" (一旦激活trace,以后每次发生事件时都要trace)| "lifetime " (一旦开始trace,以后N次成功发生事件时都要trace,然后在此诊断事件中禁用trace)| "level " (当trace第一次被激活,设置初始化级别为N,之后激活的trace的级别则由trace type来决定)|"type " (如何修改以后激活的trace的级别)
trace type:
"increment" 升高级别直至最高
"decrement" 降低级别到0并且禁用
"constant" 保持级别不变
此外,对于trace的指定,如果设置诊断事件是immediate,那么意味着trace将不会等待诊断事件,在trace qualifier中只需要设置trace的级别,lifetime默认为1。

对于设置诊断事件,Oracle数据库提供了四个跟踪信息的类别可以供我们来使用:
Ø 类别一:Dump Something
这个类别的Trace文件是无条件立即生成的,一般都是dump出Oracle数据库的数据,例如查看重做日志文件的头或者是查看控制文件中的内容等。这类的诊断事件是不可以在INIT或者SPFILE的初始化参数文件中指定的。
Ø 类别二:Trap on Error
这个类别的诊断事件是让Oracle每次生成一个errorstack的错误信息的trace文件。
Ø 类别三:Change execution path
这个类别的诊断事件主要是用于修改某些代码段的可执行路径。例如,设置诊断事件10269就可以让Oracle数据库的后台SMON进程不再进行自由空间的重组的操作。
Ø 类别四:Trace something
这个类别的诊断事件主要是用于某种特殊的目的而需要获取相应的trace信息,例如对sql调优。最常见的诊断事件10046就是让Oracle数据库去跟踪每条执行的sql语句的访问路径。
每种类别的诊断事件都有一种或者多种级别,级别有以下四种表现形式:
Ø Range,例如从1到10
Ø bitmask 例如0x01 0x02 0x04 0x08 0x10
Ø flag 例如0代表off,1代表on
Ø identifier 例如object id, memory address等等

在设置使用各种诊断事件的时候,有一些事项是需要注意的:
Ø 确定使用的诊断事件对于当前的Oracle数据库版本是合法的:因为对于不同版本的Oracle数据库来说,诊断事件的含义和用法都有所不同。
Ø 确定使用的诊断事件允许设定的级别,在很多时候设定的级别不同是会影响到诊断事件所代表的行为的。
Ø 在INITSID.ORA文件中设置的任何诊断事件,如果Oracle数据库需要升级,一定要提前注释或者取消。

大部分的诊断事件的数值都是在10000至10999范围内,使用如下的脚本可以查看到所有的诊断事件:
SET SERVEROUTPUT ON
DECLARE
err_msg VARCHAR2(120);
BEGIN
dbms_output.enable (1000000);
FOR err_num IN 10000..10999
LOOP
err_msg := SQLERRM (-err_num);
IF err_msg NOT LIKE '%Message '||err_num||' not found%' THEN
dbms_output.put_line (err_msg);
END IF;
END LOOP;
END;
/
在UNIX系统中,可以在$ORACLE_HOME/rdbms/mesg/oraus.msg这个文件中找到所有的诊断事件的名称和定义。使用如下脚本可以输出所有的详细的诊断事件的信息:
event=10000
while [ $event -ne 10999 ]
do
event=`expr $event + 1`
oerr ora $event
done

使用如下脚本可以检查当前会话中设置了哪些诊断事件:
SET SERVEROUTPUT ON
DECLARE
l_level NUMBER;
BEGIN
FOR l_event IN 10000..10999
LOOP
dbms_system.read_ev (l_event,l_level);
IF l_level > 0 THEN
dbms_output.put_line ('Event '||TO_CHAR (l_event)||
' is set at level '||TO_CHAR (l_level));
END IF;
END LOOP;
END;
/

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/92530/viewspace-506543/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/92530/viewspace-506543/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值