一、关于基础表
Oracle 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 TYPEPUBLIC SQL_PLAN_TABLE_TYPE SYNONYMSYS PLAN_TABLE$ TABLEPUBLIC PLAN_TABLE SYNONYMEXFSYS EXF$PLAN_TABLE TABLESQL> 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_TYPEPUBLIC PLAN_TABLE SYS PLAN_TABLE$从上面的结果可以看出,PLAN_TABLE正是基于PLAN_TABLE$的同义词。
二、关于plustrace角色
和Oracle9i一样,10g中plustrace角色默认也是disabled的。如果使用非授权用户打开Oracle trace功能会得到以下的错误。
SQL> conn hr/hrConnected.SQL> set autotrace traceSP2-0618: Cannot find the Session Identifier. Check PLUSTRACE role is enabledSP2-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 existSQL> 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/hrConnected.SQL> set autotrace trace三、关于autotrace功能内部操作
默认的,在启用autotrace功能时Oracle另启用一个session,专门用于收集和输出统计信息。
SQL> set autotrace offSQL> 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 expSQL> 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 SYS8 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 statSQL> 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 SYS9 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 processedSQL> 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 6977oracle 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 5SQL> 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的连接中执行SQL语句,然后使用tkprof工具格式化USER_DUMP_FILE目录中的跟踪文件。
$ tkprof randy_ora_9080.trc 9080.txt$ more 9080.txt......select *from jobscall count cpu elapsed disk query current rows------- ------ -------- ---------- ---------- ---------- ---------- ----------Parse 2 0.01 0.02 0 0 0 0Execute 2 0.00 0.00 0 0 0 0Fetch 6 0.00 0.04 6 18 0 38------- ------ -------- ---------- ---------- ---------- ---------- ----------total 10 0.02 0.06 6 18 0 38Misses in library cache during parse: 1Optimizer mode: ALL_ROWSParsing user id: 55Rows 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 298SQL> 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 DEFAULTPROCEDURE 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 12569SQL> 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 18Unix 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.trcSQL> oradebug SESSION_EVENT 10046 trace name context off;Statement processed.
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29563200/viewspace-1145484/
,如需转载,请注明出处,否则将追究法律责任。