zhuqibs
作者zhuqibs2020-04-08 00:13
软件开发工程师, Adidas

Oracle 10046事件详解

字数 4421阅读 1351评论 0赞 6

10046事件说明10046事件是Oracle提供的内部事件,是对SQL_TRACE的增强.
10046事件可以设置以下四个级别:
1 - 启用标准的SQL_TRACE功能,等价于sql_trace
4 - Level 1 加上绑定值(bind values)
8 - Level 1 + 等待事件跟踪
12 - Level 1 + Level 4 + Level 8
类似sql_trace,10046事件可以在全局设置,也可以在session级设置。

开启10046事件

SQL> set autotrace off
SQL> SET LINESIZE 80 HEADING OFF FEEDBACK OFF
SELECT
RPAD('USERNAME : ' || s.username,80) ||
RPAD('OSUSER : ' || s.osuser, 80) ||
RPAD('PROGRAM : ' || s.program, 80) ||
RPAD('SPID : ' || p.spid, 80) ||
RPAD('SID : ' || s.sid, 80) ||
RPAD('SERIAL# : ' || s.serial#, 80) ||
RPAD('MACHINE : ' || s.machine, 80) ||
RPAD('TERMINAL : ' || s.terminal,80) ||
RPAD('SQL TEXT : ' || q.sql_text,80)
FROM v$session s
,v$process p
,v$sql q
WHERE s.paddr = p.addr
SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AND s.sid = '&SID'
AND s.sql_address = q.address(+)
AND s.sql_hash_value = q.hash_value(+);
16 17 Enter value for sid: 102

USERNAME : STAR
OSUSER : oracle
PROGRAM : sqlplus@db01 (TNS V1-V3)
SPID : 26230
SID : 102
SERIAL# : 878
MACHINE : db01
TERMINAL :
SQL TEXT : SELECT ROWID RID FROM COMMUL_INV WHERE ITEMNUMBER NOT LIKE '41%'

SQL> oradebug setospid 26230
Oracle pid: 55, Unix process pid: 26230, image: oracle@db01 (TNS V1-V3)
SQL> oradebug event 10046 trace name context forever,level 12
Statement processed.
SQL> oradebug event 10046 trace name context off
Statement processed.
SQL> oradebug tracefile_name
/home/oracle/admin/commdb/udump/ora_26230.trc
SQL>

SQL> alter session set events '10046 trace name context forever ,level 12' ;

会话已更改。

关闭10046事件

SQL> alter session set events '10046 trace name context off' ;

会话已更改。

SQL> exec dbms_system.set_SQL_TRACE_in_session(127,31923,true);
SQL> select * from dual;
SQL> exec dbms_system.set_SQL_TRACE_in_session(127,31923,false);


当我们使用sql_trace/10046等事件进行进程跟踪时,会生成跟踪文件.跟踪文件名称由以下几部分组成:

_ora_.trc

以下脚本用户获得跟踪文件名称:

---- 当前 session < xmlnamespace prefix ="o" />
SELECT d.value|| '/' ||lower(rtrim(i.instance, chr( 0 )))|| '_ora_' ||p.spid|| '.trc' trace_file_name
from
( select p.spid from v$mystat m,v$session s, v$process p
where m.statistic# = 1 and s.sid = m.sid and p.addr = s.paddr) p,
( select t.instance from v$thread t,v$parameter v
where v.name = 'thread' and (v.value = 0 or t.thread# = to_number(v.value))) i,
( select value from v$parameter where name = 'user_dump_dest' ) d;
---- 其他用户 session
SELECT d.value|| '/' ||lower(rtrim(i.instance, chr( 0 )))|| '_ora_' ||p.spid|| '.trc' trace_file_name
from
( select p.spid from v$session s, v$process p
where s.sid= '127' and s. SERIAL#= '31923' and p.addr = s.paddr) p,
( select t.instance from v$thread t,v$parameter v
where v.name = 'thread' and (v.value = 0 or t.thread# = to_number(v.value))) i,
( select value from v$parameter where name = 'user_dump_dest' ) d;

SELECT a.VALUE
|| b.symbol
|| c.instance_name
|| '_ora_'
|| d.spid
|| '.trc' trace_file
FROM (SELECT VALUE
FROM v$parameter
WHERE NAME = 'user_dump_dest') a,
(SELECT SUBSTR (VALUE, -6, 1) symbol
FROM v$parameter
WHERE NAME = 'user_dump_dest') b,
(SELECT instance_name
FROM v$instance) c,
(SELECT spid
FROM v$session s, v$process p, v$mystat m
WHERE s.paddr = p.addr AND s.SID = m.SID AND m.statistic# = 0) d
/

SQL> select sid,serial#,username from v$session
2 where username is not null;

SID SERIAL# USERNAME


8 2041 SYS
9 437 EYGLE

设置跟踪:
SQL> exec dbms_system.set_sql_trace_in_session(9,437,true)

PL/SQL procedure successfully completed.

....
可以等候片刻,跟踪session执行任务,捕获sql操作...
....

停止跟踪:
SQL> exec dbms_system.set_sql_trace_in_session(9,437,false)

PL/SQL procedure successfully completed.

执行跟踪:
SQL> exec dbms_system.set_ev(9,437,10046,8,'eygle');

PL/SQL procedure successfully completed.

结束跟踪:
SQL> exec dbms_system.set_ev(9,437,10046,0,'eygle');

PL/SQL procedure successfully completed.

当我们通过alter session的方式设置了sql_trace,这个设置是不能通过show parameter的方式得到的,我们需要通过dbms_system.read_ev来获取:

SQL> set feedback off

SQL> set serveroutput on
SQL> declare
2 event_level number;
3 begin
4 for event_number in 10000..10999 loop
5 sys.dbms_system.read_ev(event_number, event_level);
6 if (event_level > 0) then
7 sys.dbms_output.put_line(
8 'Event ' ||
9 to_char(event_number) ||
10 ' is set at level ' ||
11 to_char(event_level)
12 );
13 end if;
14 end loop;
15 end;
16 /
Event 10046 is set at level 1

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

6

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广