10046事件详解

转载自:《10046事件详解》

一、      10046事件概述

10046是一个Oracle的内部事件(event),通过设置这个事件可以得到Oracle内部执行系统解析、调用、等待、绑定变量等详细的trace信息,即帮助我们解析一条/多条SQL、PL/SQL语句的运行状态,这些状态包括:Parse/Fetch/Execute三个阶段中遇到的等待事件、消耗的物理和逻辑读、CPU时间、执行计划等。它不仅为我们揭示了一条、多条SQL的运行情况,同时还能帮我们分析一些DDL维护命令的内部工作原理,RMAN、Data Pump Expdp/impdp等工具缓慢问题。对于SQL性能优化、分析系统的性能有着非常重要的作用。

 

二、      10046运行级别

 

 

Level 0

停用SQL跟踪,相当于SQL_TRACE=FALSE,无任何输出

Level 1

标准SQL跟踪,相当于SQL_TRACE=TRUE;

输出 …APPNAME(应用程序名),PARSING IN CURSOR,PARSE ERROR(SQL解析),EXEC(执行),FETCH(获取数据),UNMAP,SORT UNMAP(排序,临时段),ERROR,STAT(执行计划),XCTEND(事务)等行

Level 4

在level 1的基础上增加绑定变量的信息,即好含1信息+binding events

Level 8

在level 1的基础上增加等待事件的信息,即包含1信息+waiting events

Level 12

level 1的基础上增加绑定变量和等待事件的信息,即包含148的信息

 

三、      10046 trace文件路径

从11gR1开始,Oracle引入了新的诊断结构,以参数DIAGNOSTIC_DEST控制存放trace文件与core文件的路径。可以用以下命令,获取DIAGNOSTIC_DEST的位置:

    SQL> show parameter diagnostic_dest;

    11gR1以前,如果是用户进程,10046 trace文件会被生成在user_dump_dest下,如果是后台进程,trace文件会被生成在background_dump_dest下,下面的命令可以显示user_dump_dest:

    SQL> show parameter user_dump_dest ;

    SQL> show parameter background_dump_dest;

 

注意:通过设定tracefile_identifier即alter session set tracefile_identifier='mytrace' ,通过这个设置可以帮助我们更容易的找到生成的trace文件。

 

扩展:

(1)可以通过SQL获取当前session的跟踪文件位置:

select

a.value || '/' || b.instance_name || '_ora_' || c.spid || '.trc' trace_file

from

(select value from v$parameter where name= 'user_dump_dest') a,

(select instance_name from v$instance) b,

(select spid from v$process where addr=(select paddr from v$session where sid=(select distinct sid from v$mystat))) c;

或者

select tracefile from v$process where addr=(select paddr from v$session where sid=(select distinct sid from v$mystat));

 

 

四、      10046 trace相关参数

 

1.          timed_statistics

timed_statistics这个参数决定了是否收集与时间相关的统计信息,如果这个参数为FALSE的话,那么SQL Trace的结果基本没有多大的用处,默认情况下这个参数设置为TRUE。

show parameter timed_statistics ;

ALTER SESSION SET timed_statistics=true ;

2.          max_dump_file_size

max_dump_file_size这个参数指定dump文件的大小,也就是决定是否限制SQL Trace文件的大小,在一个很忙的系统上面做SQL Trace的话可能会生成很多的信息,因此最好在会话级别将这个参数设置成unlimited。

show parameter max_dump_file_size;

ALTER SESSION SET max_dump_file_size=unlimited ;

3.          tracefile_identifier

tracefile_identifier这个参数给Trace文件设置识别字符串,是个非常有用的参数,设置一个易读的字串能更快的找到Trace文件。

show parameter  tracefile_identifier;

ALTER SESSION SET tracefile_identifier=’my_trace_session’;

 

 

4.          diagnostic_dest

diagnostic_dest这个参数11g新增的,用于控制存放trace文件与core文件的路径,默认是$ORACLE_BASE目录。

show parameter diagnostic_dest; 命令用于查看其目录

 

5.          user_dump_dest

user_dump_dest参数指定用户进程trace文件目录。

show parameter user_dump_dest ; 命令可以产看其目录

alter system set user_dump_dest ='/U01/app/oracle/diag/rdbms/masterdb/masterdb/trace' scope=both; 命令用于更改其目录

6.          background_dump_dest

background_dump_dest参数用于后台进程产生的trace文件存储目录下。

show parameter background_dump_dest ; 命令可以查看其目录

alter system set

background_dump_dest='/U01/app/oracle/diag/rdbms/masterdb/masterdb/trace' scope=both; 命令用于更改其目录

 

注意:如果想要设置其他进程的上述参数,需要通过DBMS包设置,但tracefile_identifier是无法在别的会话中修改。

具体设置命令为:

SYS.DBMS_SYSTEM.SET_BOOL_PARAM_IN_SESSION(:sid, :serial,'timed_statistics', true) ;

SYS.DBMS_SYSTEM.SET_INT_PARAM_IN_SESSION(:sid, :serial,'max_dump_file_size', 2147483647) ;

 

五、      10046 trace设置方法

 

1.          10046事件会话级别

 

这种方法适用于SQL语句可以在新的session创建后再运行。

语法:

alter session set events '[eventnumber|immediate] trace name eventname [forever] [, level levelnumber] : .......'

1.1 开启session sql trace

    alter session set tracefile_identifier='10046';

    alter session set timed_statistics = true;      --默认是true

    alter session set statistics_level=all;               --实例级别设置需要注意,会消耗大量的CPU

    alter session set max_dump_file_size = unlimited;       --默认是unlimited

    alter session set events '10046 trace name context forever,level 12'; --常用的级别是12

 

set serveroutput off;

alter session set tracefile_identifier='10046';

alter session set timed_statistics = true;

alter session set statistics_level=all;     

alter session set max_dump_file_size = unlimited;

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

 

1.2 执行要trace的SQL

select * from scott.dept;

 

1.3 关闭session sql trace

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

 

或者直接退出session

exit

1.4 查看session sql trace路径

select tracefile from v$process where addr=(select paddr from v$session where sid=(select distinct sid from v$mystat));

或者

select

a.value || '/' || b.instance_name || '_ora_' || c.spid || '.trc' trace_file

from

(select value from v$parameter where name= 'user_dump_dest') a,

(select instance_name from v$instance) b,

(select spid from v$process where addr=(select paddr from v$session where sid=(select distinct sid from v$mystat))) c;

 

或者

show parameter user_dump_dest ;

 

1.5 分析session sql trace

(1)      直接查看

 

more /U01/app/oracle/diag/rdbms/masterdb/masterdb/trace/masterdb_ora_20596_10046.trc  

 

=====================

PARSING IN CURSOR #47019101509648 len=24 dep=0 uid=0 oct=3 lid=0 tim=1477908470545403 hv=911793802 ad='74c73648' sqlid='f6hhpzwv5jrna'

select * from scott.dept

END OF STMT

PARSE#47019101509648:c=33995,e=65940,p=14,cr=62,cu=0,mis=1,r=0,dep=0,og=1,plh=3383998547,tim=1477908470545401

EXEC #47019101509648:c=0,e=17,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=3383998547,tim=1477908470545479

WAIT #47019101509648: nam='SQL*Net message to client' ela= 14 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=1477908470545527

WAIT #47019101509648: nam='Disk file operations I/O' ela= 115 FileOperation=2 fileno=4 filetype=2 obj#=87106 tim=1477908470545730

WAIT #47019101509648: nam='db file sequential read' ela= 24 file#=4 block#=130 blocks=1 obj#=87106 tim=1477908470545780

WAIT #47019101509648: nam='db file scattered read' ela= 60 file#=4 block#=131 blocks=5 obj#=87106 tim=1477908470545972

FETCH #47019101509648:c=0,e=510,p=6,cr=6,cu=0,mis=0,r=1,dep=0,og=1,plh=3383998547,tim=1477908470546076

WAIT #47019101509648: nam='SQL*Net message from client' ela= 644 driver id=1650815232 #bytes=1 p3=0 obj#=87106 tim=1477908470546764

WAIT #47019101509648: nam='SQL*Net message to client' ela= 0 driver id=1650815232 #bytes=1 p3=0 obj#=87106 tim=1477908470546816

FETCH #47019101509648:c=0,e=36,p=0,cr=1,cu=0,mis=0,r=3,dep=0,og=1,plh=3383998547,tim=1477908470546841

STAT #47019101509648 id=1 cnt=4 pid=0 pos=1 obj=87106 op='TABLE ACCESS FULL DEPT (cr=7 pr=6 pw=0 time=498 us cost=3 size=80 card=4)'

 

*** 2016-10-31 18:08:35.900

WAIT #47019101509648: nam='SQL*Net message from client' ela= 45353246 driver id=1650815232 #bytes=1 p3=0 obj#=87106 tim=1477908515900182

CLOSE #47019101509648:c=0,e=13,dep=0,type=0,tim=1477908515900388

=====================

 

 

从上面的 trace 文件我们可以看出 sql 语句经过了 parse(解析) -> exec(执行) -> fetch(从游标中获取数据) 几个过程, 其中第一句说明了当前跟踪执行的 sql 语句的概况,比如使用游标号, sql 语句的长度, 递归深度等等基本信息:

 

其中下面含义解释:

(1)第一部分整体trace概览含义

PARSING IN CURSOR #47019101509648 len=24 dep=0 uid=0 oct=3 lid=0 tim=1477908470545403 hv=911793802 ad='74c73648' sqlid='f6hhpzwv5jrna'

 

cursor

 cursor number

 len

 sql 语句长度

 dep

 sql 语句递归深度

 uid

 user id

 oct

 oracle command type

 lid

 privilege user id

 tim

 timestamp,时间戳

 hv

 hash id

 ad

 sql address 地址, 用在 v$sqltext

 sqlid

 sql id

 

(2)第二部分SQL具体执行过程以及CPU等性能指标含义

PARSE #47019101509648:c=33995,e=65940,p=14,cr=62,cu=0,mis=1,r=0,dep=0,og=1,plh=3383998547,tim=1477908470545401

EXEC #47019101509648:c=0,e=17,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=3383998547,tim=1477908470545479

FETCH #47019101509648:c=0,e=510,p=6,cr=6,cu=0,mis=0,r=1,dep=0,og=1,plh=3383998547,tim=1477908470546076

FETCH #47019101509648:c=0,e=36,p=0,cr=1,cu=0,mis=0,r=3,dep=0,og=1,plh=3383998547,tim=1477908470546841

 

c

 CPU 消耗的时间

e

 Elapsed time 

p

 number of physical reads 物理读的次数

 cr

 number of buffers retrieved for CR reads   逻辑读的数据块

cu

 number of buffers retrieved in current mode (current 模式读取的数据块)

mis

 cursor missed in the cache 库缓存中丢失的游标, 硬解析次数

r

 number of rows processed 处理的行数

dep

 递归深度

og

 optimizer mode 【1:all_rows, 2:first_rows, 3:rule, 4:choose

plh

 plan hash value

tim

 timestamp 时间戳

 

 

 

(3)第三部分执行过程中发生的等待含义

WAIT #47019101509648: nam='SQL*Net message from client' ela= 644 driver id=1650815232 #bytes=1 p3=0 obj#=87106 tim=1477908470546764

 

nam

 an event that we waited for 等待事件

ela

 此操作消耗的时间

p3

 block 块号

trm

 timestamp 时间戳

 

(4)第四部分游标执行计划含义

 

STAT #47019101509648 id=1 cnt=4 pid=0 pos=1 obj=87106 op='TABLE ACCESS FULL DEPT (cr=7 pr=6 pw=0 time=498 us cost=3 size=80 card=4)'

 

cnt

 当前行源返回的行数

pid

 parent id of this row source 当前行源的父结点 id

pos

 position in explain plan 执行计划的位置

obj

 object id of row source (if this is a base object)

op 

 the row source access operation

上述逻辑读为7,物理读为6,消耗时间为498us,消耗3,返回记录大小80B,记录数4

 

 

(2)       tkprof查看

tkprof /U01/app/oracle/diag/rdbms/masterdb/masterdb/trace/masterdb_ora_20596_10046.trc   10046_tkprof.trc

 

TKPROF: Release 11.2.0.4.0 - Development on Mon Oct 31 18:41:56 2016

 

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

 

Trace file: /U01/app/oracle/diag/rdbms/masterdb/masterdb/trace/masterdb_ora_20687_10046.trc

Sort options: default

 

********************************************************************************

count    = number of times OCI procedure was executed

cpu      = cpu time in seconds executing

elapsed  = elapsed time in seconds executing

disk     = number of physical reads of buffers from disk

query    = number of buffers gotten for consistent read

current  = number of buffers gotten in current mode (usually for update)

rows     = number of rows processed by the fetch or execute call

********************************************************************************

 

********************************************************************************

 

SQL ID: f6hhpzwv5jrna Plan Hash: 3383998547

 

select *

from

 scott.dept

 

 

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse        1      0.03       0.06         14         62          0           0

Execute      1      0.00       0.00          0          0          0           0

Fetch        2      0.00       0.00          6          7          0           4

------- ------  -------- ---------- ---------- ---------- ----------  ----------

total        4      0.03       0.06         20         69          0           4

 

Misses in library cache during parse: 1

Optimizer mode: ALL_ROWS

Parsing user id: SYS

Number of plan statistics captured: 1

 

Rows (1st) Rows (avg) Rows (max)  Row Source Operation

---------- ---------- ----------  ---------------------------------------------------

         4          4          4  TABLE ACCESS FULL DEPT (cr=7 pr=6 pw=0 time=498 us cost=3 size=80 card=4)

 

 

Elapsed times include waiting on following events:

  Event waited on                             Times   Max. Wait  Total Waited

  ----------------------------------------   Waited  ----------  ------------

  SQL*Net message to client                       2        0.00          0.00

  Disk file operations I/O                        1        0.00          0.00

  db file sequential read                         1        0.00          0.00

  db file scattered read                          1        0.00          0.00

  SQL*Net message from client                     2       45.35         45.35

********************************************************************************

其中有Misses in library cache during parse :1  则表明解析的时候库缓存丢失游标,  也就是说发生了一次硬解析。

 

http://blog.itpub.net/27067062/viewspace-2127398/

 

 

注意:

如果session没有被彻底地关闭并且跟踪被停止了,某些重要的trace信息的可能会丢失。这里我们将"statistics_level"设置为all,这是因为有可能这个参数在系统级不是默认值"TYPICAL"(比如 BASIC)。为了收集性能相关问题的信息我们需要打开某个级别的statistics。我们推荐在 session 级将这个参数设置成 ALL 以便于收集更多的信息,尽管这不是必须的。

 

2.          10046事件进程级别跟踪

 

如果需要跟踪一个已经存在session,可以用 oradebug连接到session上,并发起10046 trace。也可以通过DBMS_SYSTEM.SET_EV系统包来实现。

 

2.1 Oradebug分析其他用户进程trace

 

查找要跟踪的session信息:

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

 

       SID    SERIAL# USERNAME

---------- ---------- ------------------------------

        18        663 SYS

       135      17081 SYS

       197      38741 SCOTT

       205       1491 SCOTT

 

根据session信息找到对应的进程号SPID

select p.PID,p.SPID,s.SID from v$process p,v$session s

     where s.paddr = p.addr and s.sid = &SESSION_ID ;

Enter value for session_id: 205

       PID SPID                            SID

---------- ------------------------ ----------

        39 25620                           205

 

 

开启进程追踪:

SQL> oradebug setospid 25620

Oracle pid: 39, Unix process pid: 25620, image: oracle@node4 (TNS V1-V3)

SQL> oradebug unlimit

Statement processed.

SQL> oradebug event 10046 trace name context forever,level 12

Statement processed.

 

###也可以通过oradebug使用 'setorapid'命令连接到一个session,即oradebug setorapid 39

 

 

 

执行查询:

SQL> select * from dept where deptno=10;

 

    DEPTNO DNAME          LOC

---------- -------------- -------------

        10 ACCOUNTING     NEW YORK

 

关闭oradebug跟踪:

 

oradebug event 10046 trace name context off

 

查看追踪文件并分析:

 

SQL>  select tracefile from v$process where addr=(select paddr from v$session where sid=205);

 

TRACEFILE

--------------------------------------------------------------------------------

/U01/app/oracle/diag/rdbms/masterdb/masterdb/trace/masterdb_ora_25620.trc

 

可以通过直接查看或者tkprof分析上述trace文件,原理同上。

 

2.2 DBMS_SYSTEM.SET_EV分期其他用户进程trace

 

语法格式:

exec DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(SID,SERIAL#, SQL_TRACE) ;

         sid:会话sid

         serial#:会话serial#

         sql_trace:true or false

exec  dbms_system.SET_EV(si,se,ev,le,nm) ;

         si:会话sid,来自v$session

         se:会话serial#,来自v$session

         ev:跟踪事件Num,如10046

         le:跟踪事件级别,如1,2,4,8,12

         nm:会话用户名,来自v$session

 

注意:如果想要设置其他进程的上述参数,需要通过DBMS包设置,但tracefile_identifier是无法在别的会话中修改。

具体设置命令为:

SYS.DBMS_SYSTEM.SET_BOOL_PARAM_IN_SESSION(:sid, :serial,'timed_statistics', true) ;

SYS.DBMS_SYSTEM.SET_INT_PARAM_IN_SESSION(:sid, :serial,'max_dump_file_size', 2147483647) ;

 

 

查询获得需要跟踪的session信息:

 

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

 

       SID    SERIAL# USERNAME

---------- ---------- ------------------------------

       135      17081 SYS

       197      38741 SCOTT

 

执行现有会话进程跟踪:

 

 

SQL> exec dbms_system.SET_EV(197,38741,10046,12,'SCOTT') ;

 

PL/SQL procedure successfully completed.

 

SQL> exec DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(197,38741,true) ;

 

PL/SQL procedure successfully completed.

 

 

执行查询操作:

 

SQL> select * from dept where deptno<=30;

 

    DEPTNO DNAME          LOC

---------- -------------- -------------

        10 ACCOUNTING     NEW YORK

        20 RESEARCH       DALLAS

        30 SALES          CHICAGO

 

结束会话跟踪:

 

SQL> exec dbms_system.SET_EV(197,38741,10046,0,'SCOTT') ;

 

PL/SQL procedure successfully completed.

 

SQL> exec DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(197,38741,false) ;

 

PL/SQL procedure successfully completed.

 

 

跟踪文件分析:

 

SQL> select tracefile from v$process where addr=(select paddr from v$session where sid=197);

 

TRACEFILE

--------------------------------------------------------------------------------

/U01/app/oracle/diag/rdbms/masterdb/masterdb/trace/masterdb_ora_24413.trc

 

或者

select pa.value || '/' || i.instance_name||'_ora_'||ps.spid||'.trc'

from (select  value from v$parameter where name= 'user_dump_dest') pa,

     (select s.sid sid,p.spid spid from v$session s,v$process p where s.PADDR=p.ADDR and s.sid=&&sid) ps,

     (select instance_name from v$instance) i;

 

通过直接查看或者tkprof分析,原理同上。

 

 

3.          10046事件实例级别跟踪

 

在实例层设置跟踪需要非常小心,这是因为整体性能会由于所有session都被跟踪而受到影响,这个设置将会跟踪在这个参数设置“以后”创建的每个session。已经存在的session不会被跟踪,系统层的10046跟踪适用于当我们知道问题session会出现,但是不能预先识别它的时候,在这种情况下,可以打开系统层跟踪一小段时间,当问题被重现以后立即将其关闭,然后从已经生成的trace中查找需要的信息,用以下命令打开系统层的跟踪:

 

    alter system set events '10046 trace name context forever,level 12'

 

用以下命令关闭在所有session中的10046跟踪:

 

    alter system set events '10046 trace name context off';

 

4.          10046初始化参数实例级别跟踪

 

设置以下参数并重新启动实例后,实例上所有的session都会打开跟踪。

event="10046 trace name context forever,level 12"

如果要关闭可以通过移除这个参数并且重启实例,或者使用下面的alter system命令可以关闭跟踪。

    alter system set events '10046 trace name context off';

5.          10046事件logon trigger跟踪

 

有的时候当需要跟踪某个特定用户的操作时,可以使用logon trigger来打开跟踪

 

   CREATE OR REPLACE TRIGGER SYS.set_trace

   AFTER LOGON ON DATABASE

   WHEN (USER like '&USERNAME')

   DECLARE

   lcommand varchar(200);

   BEGIN

   EXECUTE IMMEDIATE 'alter session set tracefile_identifier=''From_Trigger''';

   EXECUTE IMMEDIATE 'alter session set statistics_level=ALL';

   EXECUTE IMMEDIATE 'alter session set max_dump_file_size=UNLIMITED';

   EXECUTE IMMEDIATE 'alter session set events ''10046 trace name context forever, level 12''';

   END set_trace;

   /

 

   需要注意的事,为了能打开跟踪session, 执行trigger的用户需要被显式地授予'alter session'权限

 

   grant alter session to user_db

 

6.          10046事件DBMS Monitor跟踪

 

 

六、      参考文档:

1、tkprof分析trace文件

http://www.cnblogs.com/luoyx/archive/2012/05/19/2508890.html

 

2、10046 trace打开方法

http://blog.sina.com.cn/s/blog_61cd89f60102edlx.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值