Chinaunix首页 | 论坛 | 博客
  • 博客访问: 296456
  • 博文数量: 50
  • 博客积分: 2855
  • 博客等级: 上尉
  • 技术积分: 353
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-08 13:43
文章分类

全部博文(50)

文章存档

2019年(1)

2016年(2)

2015年(6)

2014年(2)

2013年(4)

2012年(34)

2011年(1)

分类: Oracle

2012-08-14 14:58:25

一、关于基础表
10G之前,启用AUTOTRACE功能需要手工创建plan_table表,创建脚本为$ORACLE_HOME/rdbms/admin/utlxplan.sql。但在10g中,已经默认创建了PLAN_TABLE$的基表,并以public用户创建了相应的同义词PUBLIC。
SQL> select owner,object_name,OBJECT_TYPE from dba_objects where object_name like '%PLAN_TABLE%';

OWNER                          OBJECT_NAME          OBJECT_TYPE
------------------------------ -------------------- -------------------
SYS                            SQL_PLAN_TABLE_TYPE  TYPE
PUBLIC                         SQL_PLAN_TABLE_TYPE  SYNONYM
SYS                            PLAN_TABLE$          TABLE
PUBLIC                         PLAN_TABLE           SYNONYM
EXFSYS                         EXF$PLAN_TABLE       TABLE

SQL> select * from dba_synonyms where SYNONYM_NAME like '%PLAN_TABLE%';
 
OWNER          SYNONYM_NAME           TABLE_OWNER                    TABLE_NAME                     DB_LINK
-------------- ---------------------- ------------------------------ ------------------------------ --------
PUBLIC         SQL_PLAN_TABLE_TYPE    SYS                            SQL_PLAN_TABLE_TYPE
PUBLIC         PLAN_TABLE             SYS                            PLAN_TABLE$
 
从上面的结果可以看出,PLAN_TABLE正是基于PLAN_TABLE$的同义词。
 
二、关于plustrace角色
 
和Oracle9i一样,10g中plustrace角色默认也是disabled的。如果使用非授权用户打开Oracle trace功能会得到以下的错误。
 
SQL> conn hr/hr
Connected.
SQL> set autotrace trace
SP2-0618: Cannot find the Session Identifier.  Check PLUSTRACE role is enabled
SP2-0611: Error enabling STATISTICS report
这时需要执行$ORACLE_HOME/sqlplus/admin/plustrce.sql脚本,手工创建plustrace角色。
SQL> @$ORACLE_HOME/sqlplus/admin/plustrce.sql;
SQL>
SQL> drop role plustrace;
drop role plustrace
          *
ERROR at line 1:
ORA-01919: role 'PLUSTRACE' does not exist


SQL> create role plustrace;

Role created.

SQL> grant select on v_$sesstat to plustrace;
Grant succeeded.

SQL> grant select on v_$statname to plustrace;

Grant succeeded.

SQL> grant select on v_$mystat to plustrace;

Grant succeeded.

SQL> grant plustrace to dba with admin option;

Grant succeeded.

SQL> set echo off
 
接下来就可以手工将plustrace角色授予需要的角色或用户,或者直接将其授予public角色,这样所有public角色的用户都有使用autotrace功能的权限了。
 
SQL> grant plustrace to hr;

Grant succeeded.

SQL> conn hr/hr
Connected.
SQL> set autotrace trace
 
三、关于autotrace功能内部操作
 
默认的,在启用autotrace功能时Oracle另启用一个session,专门用于收集和输出统计信息。
 
SQL> set autotrace off
SQL> select sid,serial#,username from v$session where username is not null;

       SID    SERIAL# USERNAME
---------- ---------- ------------------------------
       146        906 SYS
       159          3 SYS
......
SQL> set autotrace on exp
SQL> select sid,serial#,username from v$session where username is not null;

       SID    SERIAL# USERNAME
---------- ---------- ------------------------------
       129          6 SYSMAN
       135          4 DBSNMP
       136        356 SYSMAN
       143         45 SYSMAN
       145         10 SYSMAN
       146        906 SYS
       149         38 DBSNMP
       159          3 SYS

8 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3733760267

--------------------------------------------------------------------------------------------
| Id  | Operation                | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |                 |     1 |   108 |     0   (0)| 00:00:01 |
|   1 |  NESTED LOOPS            |                 |     1 |   108 |     0   (0)| 00:00:01 |
|*  2 |   FIXED TABLE FULL       | X$KSUSE         |     1 |    95 |     0   (0)| 00:00:01 |
|*  3 |   FIXED TABLE FIXED INDEX| X$KSLED (ind:2) |     1 |    13 |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("S"."KSUUDLNA" IS NOT NULL AND "S"."INST_ID"=USERENV('INSTANCE') AND
              BITAND("S"."KSSPAFLG",1)<>0 AND BITAND("S"."KSUSEFLG",1)<>0)
   3 - filter("S"."KSUSEOPC"="E"."INDX")
而收集统计信息的时候,则多出一个session。
 
SQL> set autotrace on stat
SQL> select sid,serial#,username from v$session where username is not null;

       SID    SERIAL# USERNAME
---------- ---------- ------------------------------
       126        692 SYS
       129          6 SYSMAN
       135          4 DBSNMP
       136        356 SYSMAN
       143         45 SYSMAN
       145         10 SYSMAN
       146        906 SYS
       149         38 DBSNMP
       159          3 SYS
 
9 rows selected.

Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          0  consistent gets
          0  physical reads
          0  redo size
        695  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          9  rows processed
SQL> select a.sid,a.serial#,a.username,b.pid,b.spid
  2  from v$session a,v$process b
  3  where a.paddr=b.addr and a.username is not null;

       SID    SERIAL# USERNAME                              PID SPID
---------- ---------- ------------------------------ ---------- ------------
       159          3 SYS                                    15 4261
       146        906 SYS                                    18 6977
       126        692 SYS                                    18 6977
......

9 rows selected.

$ ps -ef|grep -v grep|grep 6977
oracle    6977  6976  0 21:22 ?        00:00:00 oraclerandy (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
四、关于DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION
其实我们更多的时候需要跟踪的其他用户的进程,而很多这样的用户可能没有被授予或者不允许授予plustrace角色。这时可以使用DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION过程来实现对进程的跟踪,该过程需要提供用户进程的sid和serial#。
 
SQL> select sid,serial#  from v$session where username ='HR';

       SID    SERIAL#
---------- ----------
       159          5

SQL> exec dbms_system.SET_SQL_TRACE_IN_SESSION(159,5,true);

PL/SQL procedure successfully completed.

SQL> select a.sid,a.serial#,a.username,b.pid,b.spid
  2  from v$session a,v$process b
  3  where a.paddr=b.addr and a.username='HR';

       SID    SERIAL# USERNAME                              PID SPID
---------- ---------- ------------------------------ ---------- ------------
       159          5 HR                                     15 9080
回到用户HR的连接中执行语句,然后使用tkprof工具格式化USER_DUMP_FILE目录中的跟踪文件。
$ tkprof randy_ora_9080.trc 9080.txt
$ more 9080.txt

......
select *
from
 jobs
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        2      0.01       0.02          0          0          0           0
Execute      2      0.00       0.00          0          0          0           0
Fetch        6      0.00       0.04          6         18          0          38
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total       10      0.02       0.06          6         18          0          38

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 55

Rows     Row Source Operation
-------  ---------------------------------------------------
     19  TABLE ACCESS FULL JOBS (cr=9 pr=6 pw=0 time=42771 us)
......
从跟踪文件中,可以发现很多关于Oracle在实现用户需求时的内部操作,深入研究确实会有很多的收获。不过这里我们关心的是上面摘录的部分,可以看到select * from jobs执行计划和相关的统计信息。
 
五、使用会话级10046事件
 
除了上述的方法外,还可以使用会话级的10046事件来实现进程跟踪。

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

SQL> alter session set events '10046 trace name context off';
如果用户没有alter session的权限,可以使用DBMS_SYSTEM.SET_EV过程来实现对用户进程的跟踪。
SQL> desc DBMS_SYSTEM

......
PROCEDURE SET_EV
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SI                             BINARY_INTEGER          IN
 SE                             BINARY_INTEGER          IN
 EV                             BINARY_INTEGER          IN
 LE                             BINARY_INTEGER          IN
 NM                             VARCHAR2                IN
......

几个参数分别是进程sid,serial#,event name,level,username。
 
SQL> select sid,serial#  from v$session where username ='HR';

       SID    SERIAL#
---------- ----------
       154        298

SQL> exec dbms_system.set_ev(154,298,10046,12,'');

PL/SQL procedure successfully completed.

SQL> select a.sid,a.serial#,a.username,b.pid,b.spid
  2  from v$session a,v$process b
  3  where a.paddr=b.addr and a.username='HR';

       SID    SERIAL# USERNAME                              PID SPID
---------- ---------- ------------------------------ ---------- ------------
       154        298 HR                                     15 9903
 
使用tkprof格式化跟踪文件,可以得到和第四部分相同的输出。
 
六、使用DBMS_MONITOR

DBMS_MONITOR包也非常的强大,可以提供基于客户ID、服务模块以及级和会话级的跟踪和统计。这里使用SESSION_TRACE_ENABLE来实现数据库级的跟踪。
SQL> desc dbms_monitor
......
PROCEDURE SESSION_TRACE_DISABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SESSION_ID                     BINARY_INTEGER          IN     DEFAULT
 SERIAL_NUM                     BINARY_INTEGER          IN     DEFAULT
PROCEDURE SESSION_TRACE_ENABLE
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 SESSION_ID                     BINARY_INTEGER          IN     DEFAULT
 SERIAL_NUM                     BINARY_INTEGER          IN     DEFAULT
 WAITS                          BOOLEAN                 IN     DEFAULT
 BINDS                          BOOLEAN                 IN     DEFAULT
......

SQL> select a.sid,a.serial#,a.username,b.pid,b.spid
  2  from v$session a,v$process b
  3  where a.paddr=b.addr and a.username = 'HR';

       SID    SERIAL# USERNAME                              PID SPID
---------- ---------- ------------------------------ ---------- ------------
       159        348 HR                                     18 12569

SQL> exec dbms_monitor.SESSION_TRACE_ENABLE(159,348);

PL/SQL procedure successfully completed.

SQL> exec dbms_monitor.SESSION_TRACE_DISABLE(159,348);

PL/SQL procedure successfully completed.
使用这种方法也可以实现对会话的跟踪。
 
七、使用oradebug实现跟踪
oradebug是一个非常强大的工具,广泛的使用在设置debug事件和产生dumps。我们也可以通过这个工具,设置会话的10046事件,从而实现对会话的跟踪。说到底,还是10046事件的一种实现方式,但是由于它强大的功能本人对它非常的钟爱,所以单独列了出来。
接上面的实验,我们可以看到用户HR的PID为18,下面我们通过oradebug实现对该进程的跟踪。
SQL> oradebug SETORAPID 18
Unix process pid: 12569, image: oracle@oracle (TNS V1-V3)

SQL> oradebug SESSION_EVENT 10046 trace name context forever,level 12;
Statement processed.

SQL> oradebug tracefile_name
/u01/oracle/admin/randy/udump/randy_ora_12569.trc

SQL> oradebug SESSION_EVENT 10046 trace name context off;
Statement processed.
 
阅读(964) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~