1. 程式人生 > >Oracle AWR,SQL_TRACE,10046,DBMS_PROFILER 等使用

Oracle AWR,SQL_TRACE,10046,DBMS_PROFILER 等使用

Oracle AWR,SQL_TRACE,10046,DBMS_PROFILER 等使用

1 AWR 工具的使用及優化

 1 10g預設安裝

 select * from dba_hist_wr_control

325518186 +00 01:00:00.000000 +07 00:00:00.000000 DEFAULT

325518186 +00 00:30:00.000000 +10 00:00:00.000000 DEFAULT

--可通過以下方法把快照收集時間間隔修改為30 分鐘,保留時間從7 天修改為10 天:

---擁有dba許可權的使用者

begin

dbms_workload_repository.modify_snapshot_settings(interval=>30,retention=>10*24*60);

end;

/

12c

1404914474 +00 01:00:00.000000 +08 00:00:00.000000 DEFAULT 1

[[email protected] ~]$ find /u01 -name 'awrrpt.sql'

/u01/app/oracle/product/12.1.0/dbhome_1/rdbms/admin/awrrpt.sql

 

--再檢視,採集配置已經修改。

SELECT * FROM DBA_HIST_WR_CONTROL;

2 使用

@/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/awrrpt.sql

[[email protected] admin]# pwd

/u01/app/oracle/product/10.2.0/db_1/rdbms/admin

[[email protected] admin]# su - oracle

      回車生成預設的html格式,或者輸入txt格式

      回車預設取樣全天的快照,輸入1表示只顯示當天

      快照開始點 snap_id, 快照結束點snap_id,分別有對應的時間

      產生報表檔案,預設

awrrpt_1_1_3.html的報表

    file:當前目錄下

/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/awe_20131126.html

[[email protected] u01]# find / -name awrrpt_1_6038_6039.html

/home/oracle/awrrpt_1_6038_6039.html

3 分析思路

     1 cache size,觀察主機記憶體情況,判斷sga的記憶體分配是否合理

     2 load profile的transactions,判斷系統的繁忙程度

     3 load profile的hard parses和parses值看硬解析是否過多,從而定位是否存在繫結變數

     4 觀察top 5 timed events檢視系統的瓶頸所在,cpu排第一且佔用大量時間,說明正常

     5 一下order by語句,每類前幾位的sql語句,並設法優化,同時注意善於發現主要矛盾,toatl為99%的

      sql  ordered by elapsed time

      sql  ordered by cup time

      sql  ordered by gets

      sql  ordered by reads

      sql ordered by executions

      sql ordered by parse calls

   舉例

WORKLOAD REPOSITORY report for

Report Summary

Cache Sizes

Load Profile

 

  1 Load Profile

Transactions事務0.19 很小

2 排名靠前的事件

Top 5 Timed Events

 

db file sequential read 主要跟執行的sql有關

Log file switch 等待事件,---當日志組寫完後,lgwr試圖寫第一個logfile,如果此時資料庫沒有完成寫出記錄在第一個日誌組中,表示dbwr寫出太慢,解決方式:新增額外的dbwr或增加日誌組或日誌檔案的大小

可以根據公式查詢每個日誌的平均讀寫的大小量

 Average redo wirte size=(redo block written/redo writes)*512 bytes,值過小,說明系統的提交過於頻繁,(29/523)*512=

Instance Activity Stats

sql> show parameter log_buffer 檢視log_buffer的大小(一般4m),建議15-30m

SQL> show parameter log_buffer

NAME_COL_PLUS_SHO TYPE        VALUE_COL_PLUS_SH

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

log_buffer        integer     2927616

3 觀察各類開銷最大的sql

 根據db file sequential read/db file scattered read/cpu time來尋找根源

SQL ordered by Elapsed Time

中SQL Text 可以看見執行的sql語句。。。

select * from v$sql where sql_id='bmb1w8zs830up'

select * from v$sqltext  a,v$sql b

where a.hash_value=b.hash_value

and b.sql_id='bmb1w8zs830up';

 

select * from v$SQL_PLAN  a,v$sql b

where a.hash_value=b.hash_value

and b.sql_id='bmb1w8zs830up';

 

SELECT hash_value, buffer_gets, disk_reads, executions, parse_calls

  FROM V$SQLAREA

 WHERE hash_Value=4035019605;

 

select * from DBA_SOURCE where owner='GRSV5' AND TEXT LIKE '% PARTNER_LEVEL, DIRECT_OWNER%';

 

SELECT *

  FROM V$SQLAREA

 WHERE buffer_gets > 10000000 OR disk_reads > 1000000

 ORDER BY buffer_gets + 100 * disk_reads DESC;

 

4 制定總體優化方案

Redo file,批量提交,繫結變數,插入帶序列的,全部增加cache

 

SQL_TRACE/10046事件

   用來進行sql跟蹤的強有力工具,可跟蹤到sql的解析過程、執行計劃、繫結變數、遞迴呼叫等詳細資訊

 1  SQL_TRACE/10046 事件具體使用方法

  A 當前session

--開啟會話跟蹤

alter session set sql_trace=true;

--關閉會話跟蹤

alter session set sql_trace=false;

exec dbms_system.set_sql_trace_in_session(142,14,true)

exec dbms_system.set_sql_trace_in_session(142,14,false)

--開啟會話跟蹤  10046事件

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

--關閉會話跟蹤

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

SQL> show parameter max_dump_file_size

NAME                                 TYPE        VALUE

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

max_dump_file_size                   string      UNLIMITED

SQL> show parameter timed_statistics

NAME                                 TYPE        VALUE

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

timed_statistics                     boolean     TRUE

  B  指定使用者的session

SQL> select sid,serial#,username from v$session where username='SCOTT';

       SID    SERIAL# USERNAME

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

       144        556 SCOTT

 sys使用者許可權來開啟和關閉跟蹤

[[email protected] admin]$ sqlplus "/as sysdba"

SQL*Plus: Release 10.2.0.1.0 - Production on Tue Nov 26 16:36:19 2013

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production

With the Partitioning, OLAP and Data Mining options

SQL>  EXEC DBMS_SYSTEM.SET_EV(144,13,10046,8,'SCOTT');

PL/SQL procedure successfully completed.

 EXEC DBMS_SYSTEM.SET_EV(137,9,10046,8,'SCOTT');

 EXEC DBMS_SYSTEM.SET_EV(137,9,10046,0,'SCOTT');

 2 獲取跟蹤檔案

   跟蹤檔案一般位於user_dump_dest目錄下

  1 通過指令碼來定位

sql>SELECT c.value||'\'||d.instance_name||'_ora_'||a.spid||'.trc' trace_name_file

FROM v$process a, v$session b,v$parameter c,v$instance d

WHERE a.addr=b.paddr

and b.audsid=userenv('sessionid')

and c.name='user_dump_dest';

TRACE_NAME_FILE

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

F:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_40656.trc

 

SELECT c.value||'/'||d.instance_name||'_ora_'||a.spid||'.trc' trace_name_file

FROM v$process a, v$session b,v$parameter c,v$instance d

WHERE a.addr=b.paddr

and b.audsid=userenv('sessionid')

and c.name='user_dump_dest';

/u01/app/oracle/admin/grs/udump/grs_ora_5808.trc

 

[[email protected] udump]$ find /u01/app/oracle/admin/grs/udump -name grs_ora_5808.trc

  2 通過對跟蹤檔案加標示

   Alter session set tracefile_identifier='10046';

  Host dir F:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_40656.trc

  host dir F:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\*10046*

3 tkprof格式化

  Tkprof是oracletrace自帶的格式化工具

  Tkprof tracefile outputfile [options]

CMD 下 tkprof

  Tkprof F:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_10416.trc

  Tkprof F:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_13444.trc f:\trace4180.txt

Tkprof /u01/app/oracle/admin/grs/udump/grs_ora_5808.trc /u01/app/oracle/trace10046_20131126.txt

 

C:\DocumentsandSettings\yanghongquan>tkprof F:\ORACLE\PRODUCT\10.2.0\ADMIN\ORCL\UDUMP\orcl_ora_10416.trc f:

TKPROF: Release 10.2.0.1.0 - Production on Fri May 17 14:17:45 2013

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

 Dir d:\10046.txt

select * from emp1

minus

select * from emp

call     count       cpu    elapsed       disk      query    current        rows

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

Parse        1      0.00       0.00          0          2          0           0

Execute      1      0.00       0.00          0          0          0           0

Fetch        2      0.00       0.00          0         14          0           3

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

total        4      0.00       0.00          0         16          0           3

 

Misses in library cache during parse: 1

Optimizer mode: ALL_ROWS

Parsing user id: 54  

 

Rows     Row Source Operation

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

      3  MINUS  (cr=14 pr=0 pw=0 time=121 us)

     16   SORT UNIQUE (cr=7 pr=0 pw=0 time=85 us)

     16    TABLE ACCESS FULL EMP1 (cr=7 pr=0 pw=0 time=36 us)

     14   SORT UNIQUE (cr=7 pr=0 pw=0 time=30 us)

     14    TABLE ACCESS FULL EMP (cr=7 pr=0 pw=0 time=14 us)

 小結:

    1 對特定消耗資源的過程或者使用者程序啟用trace/10046

    2 通過tkprof格式化trace file

    3 分析格式化後的檔案,找出相應的瓶頸

3 計時跟解析工具

   1 sqlplus下 set timing on。可以看到執行時間,但是精度不高,有時候不準確

     set serverout on

     set timing on

declare

t number;

n number default 0;

begin

t:=DBMS_UTILITY.GET_TIME;

for i in 1..1e6 loop

n:=n+i;

end loop;

dbms_output.put_line(n||'time:'||(DBMS_UTILITY.GET_TIME-t)||'0ms');

end;

/

   --不帶括號

select dbms_utility.get_time from dual;

--帶括號

select dbms_utility.get_time() from dual;

 10g還提供了dbms_utility.get_cpu_time函式,

   2 plsql_profiler-----DBMS_PROFILER

--要利用DBMS_PROFILER包需要一些準備工作。

1 /*

1.以sysdba角色執行ORACLE_HOME/rdbms/admin/profload.sql 指令碼裝載 PL/SQL Profiler包。注意DBMS_PROFILER 必須用SYS使用者安裝。

[[email protected] ~]$ sqlplus "/as sysdba"

SQL*Plus: Release 10.2.0.1.0 - Production on Wed Nov 27 11:05:37 2013

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

Connected to:

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production

With the Partitioning, OLAP and Data Mining options

SQL> @/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/profolad.sql

SP2-0310: unable to open file "/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/profolad.sql"

SQL> !find /u01 -name profload.sql

/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/profload.sql

---/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/profload.sql

SQL> @/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/profload.sql

Package created.

Grant succeeded.

Synonym created.

Library created.

Package body created.

Testing for correct installation

SYS.DBMS_PROFILER successfully loaded.

PL/SQL procedure successfully completed.

 

2.以PLSQL執行者使用者執行ORACLE_HOME/rdbms/admin/proftab.sql指令碼建立了下列3個工具表和一個序列plsql_profiler_runnumbe用於記錄效能資料。

SQL> conn scott

Enter password:

Connected.

SQL> !find /u01 -name proftab.sql

/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/proftab.sql

SQL> @/u01/app/oracle/product/10.2.0/db_1/rdbms/admin/proftab.sql

drop table plsql_profiler_data cascade constraints

           *

ERROR at line 1:

ORA-00942: table or view does not exist

drop table plsql_profiler_units cascade constraints

           *

ERROR at line 1:

ORA-00942: table or view does not exist

drop table plsql_profiler_runs cascade constraints

           *

ERROR at line 1:

ORA-00942: table or view does not exist

drop sequence plsql_profiler_runnumber

              *

ERROR at line 1:

ORA-02289: sequence does not exist

Table created.

Comment created.

Table created.

Comment created.

Table created.

Comment created.

Sequence created.

 

12c

SQL> conn /as sysdba

Connected.

SQL> alter session set container=PDBORCL;

 

Session altered.

 

SQL> @/u01/app/oracle/product/12.1.0/dbhome_1/rdbms/admin/profload.sql

SQL> conn SOCIALDIAL/[email protected]

Connected.

SQL> !find /u01 -name proftab.sql

/u01/app/oracle/product/12.1.0/dbhome_1/rdbms/admin/proftab.sql

 

SQL> @/u01/app/oracle/product/12.1.0/dbhome_1/rdbms/admin/proftab.sql

drop table plsql_profiler_data cascade constraints

           *

        *

 

2 */

--單獨建立一個使用者作為工具表的屬主,然後授予必要的訪問許可權給需要剖析的使用者

--給所有使用者授予訪問工具表的許可權的例子

CONNECT sys/[email protected] AS SYSDBA

@$ORACLE_HOME/rdbms/admin/profload.sql

 

CREATE USER profiler IDENTIFIED BY profiler DEFAULT TABLESPACE users QUOTA UNLIMITED ON users;

--下一行適用於9i的環境,在10g中connect角色已經不再包含CREATE TABLE和CREATE SEQUENCE的許可權,需要直接顯式授權

GRANT connect TO profiler;

 

CREATE PUBLIC SYNONYM plsql_profiler_runs FOR profiler.plsql_profiler_runs;

CREATE PUBLIC SYNONYM plsql_profiler_units FOR profiler.plsql_profiler_units;

CREATE PUBLIC SYNONYM plsql_profiler_data FOR profiler.plsql_profiler_data;

CREATE PUBLIC SYNONYM plsql_profiler_runnumber FOR profiler.plsql_profiler_runnumber;

 

CONNECT profiler/[email protected]

 

@$ORACLE_HOME/rdbms/admin/proftab.sql

GRANT SELECT ON plsql_profiler_runnumber TO PUBLIC;

GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_data TO PUBLIC;

GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_units TO PUBLIC;

GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_runs TO PUBLIC;

 

--給所有使用者授予訪問工具表的許可權的例子

  Conn / as sysdba CONNECT sys/[email protected] AS SYSDBA---sysdba

    @F:\oracle\product\10.2.0\db_1\RDBMS\admin\profload.sql

Connect scott/[email protected]

   @F:\oracle\product\10.2.0\db_1\RDBMS\admin\proftab.sql

 

DBMS_PROFILER.START_PROFILER('使用者註釋');--開始對一次執行記錄資訊。

需要剖析的程式碼塊

DBMS_PROFILER.STOP_PROFILER;--結束一次執行的資訊記錄。

 例如

   1 先建立一個程式

   2 執行一個匿名塊,把這個過程作為一個整體呼叫

     DECLARE

  l_result  BINARY_INTEGER;

BEGIN

  l_result := DBMS_PROFILER.start_profiler(run_comment => 'PRIMEY0: ' || SYSDATE);

  primey0(10000);--- 'PRIMEY0需要剖析的過程名

  l_result := DBMS_PROFILER.stop_profiler;

END;

/

 

begin

   DBMS_PROFILER.START_PROFILER('bluck_foall_edit'); 

      bluck_foall_edit;

   DBMS_PROFILER.STOP_PROFILER

  end; 

  

 

DECLARE

  P_PROVIDERID VARCHAR2(32767);

  P_USERID VARCHAR2(32767);

  P_LINKID VARCHAR2(32767);

  P_LINKTYPE VARCHAR2(32767);

  P_CATAGORY VARCHAR2(32767);

  P_STATUS VARCHAR2(32767);

  P_REGISTERTYPE VARCHAR2(32767);

  P_RETURN NUMBER;

begin

   DBMS_PROFILER.START_PROFILER('DIAL_LINK_REGISTER'); 

   P_LINKID:='yyy23232';---IN OUT型別,必須使用變數

    DIAL_LINK_REGISTER ( 'GLOBALROAM', '[email protected]',  P_LINKID,  'ID', P_CATAGORY, 'STATUS', P_REGISTERTYPE, P_RETURN );

   DBMS_PROFILER.STOP_PROFILER

  end;

-----

3 */ 解析剖析的一次執行的RUNID

SELECT runid,

       run_date,

       run_comment,

       run_total_time

FROM   plsql_profiler_runs

ORDER BY runid;

  4 輸入runid

SELECT u.runid, u.unit_number, u.unit_type, u.unit_owner, u.unit_name,

       d.line#, d.total_occur—執行次數, d.total_time, d.min_time, d.max_time

FROM   plsql_profiler_units u

       JOIN plsql_profiler_data d ON u.runid = d.runid AND u.unit_number = d.unit_number

WHERE  u.runid = xxx

ORDER BY u.unit_number, d.line#;

SELECT u.runid, u.unit_number, u.unit_type, u.unit_owner, u.unit_name,

       d.line#, d.total_occur, to_char(d.total_time/100000000), d.min_time, d.max_time

FROM   plsql_profiler_units u

       JOIN plsql_profiler_data d ON u.runid = d.runid AND u.unit_number = d.unit_number

WHERE  u.runid =12 and d.total_time>=1

ORDER BY u.unit_number, d.line#;

 

  5 SELECT line || ' : ' || text

FROM   all_source

WHERE  owner = 'SCOTT' --當前會話使用者,也可以是其他使用者,比如'LT'

AND    type  = 'PROCEDURE'

AND    name  = 'PRIMEY0';

all_source中檢視程式的原始碼,具體要哪一行

 -----

Oracle自己的一個指令碼

SQL> !find /u01 -name profrep.sql

/u01/app/oracle/profrep.sql

 

SQL> @/u01/app/oracle/profrep.sql

 

--輸出每次執行的詳細報告

 

exec prof_report_utilities.print_detailed_report;

 

--輸出每個模組執行的累計報告

 

exec prof_report_utilities.print_summarized_report;

使用 prof.zip 格式化報表: 

下載prof.zip

  SQL> @D:\prof\profiler.sql------ @f:\mydb\prof\profiler.sql

/*

     RUNID RUN_DATE            RUN_COMMENT

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

         3 27-6月 -10 15:38:20 PRIMEY0

*/

--看到runid是3,然後按照提示輸入:

START profiler.sql <runid>

 當前目錄下:

C:\Documents and Settings\yanghongquan

--輸入 1 的值:  3

PL/SQL provides a mechanism to obtain timings of code execution that are accurate to 100th of a second: the DBMS_UTILTY.GET_TIME function. Yes, that's right. I said 100th of a second. 0.01秒

 DECLARE

   time_before BINARY_INTEGER;

   time_after BINARY_INTEGER;

BEGIN

   time_before := DBMS_UTILITY.GET_TIME;

  BLOCK_IP;

   time_after := DBMS_UTILITY.GET_TIME;

   DBMS_OUTPUT.PUT_LINE ('usetime=='||to_char(time_after - time_before));

END;

 

 

declare

 t number;

 n number default 0;

 begin

  t:=DBMS_UTILITY.GET_TIME;

  for i in 1 .. 1e6 loop

   n:=n+1;

   end loop;

      DBMS_OUTPUT.PUT_LINE ('usetime=='||(DBMS_UTILITY.GET_TIME-t)||'0ms');

 end;