How to trace sessions in Oracle Database
當Oracle資料庫出現效能問題時,我們通常可以利用一些效能診斷工具來跟蹤SQL的執行情況,進而根據輸出的跟蹤檔案來了解和分析資料庫內部的一些操作過程和統計資訊,找出效能瓶頸。
針對不同的需求場景,有不同的診斷工具,或者同一種工具有不同的用法。這裡就彙總下一些常用的效能診斷工具和使用場景。
跟蹤檔案
Oracle跟蹤檔案分為三種類型
- 一種是後臺報警日誌檔案,記錄資料庫在啟動、關閉和執行期間後臺程序的活動情況,如表空間建立、回滾段建立、某些alter命令、日誌切換、錯誤訊息等。在資料庫出現故障時,應首先檢視該檔案,但檔案中的資訊與任何錯誤狀態沒有必然的聯絡。後臺報警日誌檔案儲存
BACKGROUND_DUMP_DEST
- 另一種型別是DBWR、LGWR、SMON等後臺程序建立的後臺跟蹤檔案。後臺跟蹤檔案根據後臺程序執行情況產生,後臺跟蹤檔案也儲存在
BACKGROUND_DUMP_DEST
引數指定的目錄中。 - 還有一種型別是由連線到Oracle的使用者程序(Server Processes)生成的使用者跟蹤檔案。這些檔案僅在使用者會話期間遇到錯誤時產生。此外,使用者可以通過執行oracle跟蹤事件(如10046事件)來生成該類檔案,使用者跟蹤檔案儲存在
USER_DUMP_DEST
引數指定的目錄中。
命名規則
使用者程序跟蹤檔案的命名規則
[oracle_sid]_ora_[server_process_id]_[trace_id].trc
oracle_sid
,可以簡單理解為資料庫例項id,erpprod為prod;server_process_id
,oracle內部標示程序的id,可以通過查詢v$session的spid來確定;trace_id
可由tracefile_identifier
引數指定,通過查詢v$process的traceid來確定,預設為空。
存放路徑
- 由引數
user_dump_dest
指定。 - 在
SQL*Plus
中可以通過show user_dump_dest;
查詢; 或執行SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME = 'user_dump_dest';
初始化引數
為了在跟蹤檔案中更好的收集資料庫效能診斷資訊,必須先調整以下兩個引數:
TIMED_STATISTICS
用於收集與時間有關的資訊,主要從作業系統請求時間而引起的時間開銷,若需要顯示這些資訊,需設定為TRUE。MAX_DUMP_FILE_SIZE
指定跟蹤檔案的最大大小;如果跟蹤檔案很大或者不確定,需設定為足夠的大小,或者UNLIMITED
。
跟蹤當前會話
1.使用 SQL_TRACE
在SQL*Plus
中使用SQL_TRACE
,跟蹤當前會話
-- Start tracing the current session
ALTER SESSION SET SQL_TRACE = TRUE ;
-- execute your SQL to be traced --
-- Stop tracing the current session
ALTER SESSION SET SQL_TRACE = FALSE;
對例項上所有的SQL做跟蹤
-- Start tracing the whole instance
ALTER DATABASE SET SQL_TRACE = TRUE ;
-- execute your SQL to be traced --
-- Stop tracing the whole instance
ALTER SESSION SET SQL_TRACE = FALSE;
注:
- 在session級別設定,只對當前session進行跟蹤,在例項級別,會對例項上所有的SQL做跟蹤,這種方式跟蹤的SQL太多,代價是非常大的,所有很少用。
sql_trace
也可以在初始化檔案裡面設定。
2.10046事件
10046 事件主要用來跟蹤SQL語句,它並不是ORACLE官方提供給使用者的命令,在官方文件上也找不到事件的說明資訊。但是用的卻比較多,因為10046事件獲取SQL的資訊比SQL_TRACE 更多。 更有利於我們對SQL的判斷。
-- Start tracing the current session
alter session set events '10046 trace name context forever, level 12';
-- execute your SQL to be traced --
--Stop tracing the current session
alter session set events '10046 trace name context off';
10046事件級別
根據要收集資訊的詳細程度,10046事件分為了很多不同的級別,使用整數定義,常見的如下:
- Level 1: 等同於SQL_TRACE 的功能
- Level 4: 在Level 1的基礎上增加收集繫結變數的資訊
- Level 8: 在Level 1 的基礎上增加等待事件的資訊
- Level 12:等同於Level 4+Level 8, 即同時收集繫結變數資訊和等待事件資訊。
一般來說,使用Level 12
就可以收集到比較詳細的診斷資訊,包括繫結變數,等待事件等。
使用示例
初始引數設定
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;
啟動10046跟蹤事件
alter session set events '10046 trace name context forever, level 12';
-- execute your SQL to be traced --
在當前會話中,停用10046跟蹤事件,有以下兩種方法:
1)退出當前會話
select * from dual;
--exit;
2)手動使跟蹤失效
alter session set events '10046 trace name context off';
3.DBMS_SUPPORT
跟蹤當前會話除了以上兩種方式外,Oracle還提供了實用工具DBMS_SUPPORT
包,如果沒有需要手動到$ORACLE_HOME/rdbms/admin
下安裝。
主要用法如下:
--Start tracing the current session
exec sys.dbms_support.start_trace ;
-- execute your SQL to be traced --
--Stop tracing the current session
exec sys.dbms_support.stop_trace ;
跟蹤非當前會話
在效能診斷過程中,跟蹤當前會話更多的是重現問題,以確認是否存在異常情況,但限制太多,而且很難模擬生產系統當時的執行情況。因此,Oracle也提供了豐富的工具盒方法來監控正在執行的會話,以更好的適應實際應用的需求。
以下彙總一些常用方的工具,在不同的資料庫版本中,支援程度可能不一樣。
1.使用dbms_system.set_bool_param_in_session
--Start tracing other session (28,226)
exec sys.dbms_system.set_bool_param_in_session(28, 226, 'sql_trace', TRUE);
-- execute SQL in that session to be traced --
--Stop tracing other session (28,226)
exec sys.dbms_system.set_bool_param_in_session(28, 226, 'sql_trace', FALSE);
2.使用dbms_system.set_ev
--Start tracing other session (28,226)
exec dbms_system.set_ev(28, 226, 10046, 12, '');
-- execute SQL in that session to be traced --
--Stop tracing other session (28,226)
exec dbms_system.set_ev(28, 226, 10046, 0, '');
3.使用dbms_system.set_sql_trace_in_session
-Start tracing other session (28,226)
exec dbms_system.set_sql_trace_in_session(1166,30993,TRUE);
-- execute SQL in that session to be traced --
-Start tracing other session (28,226)
exec dbms_system.set_sql_trace_in_session(1166,30993,FALSE);
4.使用dbms_monitor
-Start tracing other session (28,226)
exec dbms_monitor.session_trace_enable(session_id=>28,serial_num=>226, waits=>true, binds=>true);
-- execute SQL in that session to be traced --
-Start tracing other session (28,226)
exec dbms_monitor.session_trace_disable(session_id=>28,serial_num=>226);
5.使用oradebug
--Start tracing process with pid = os_process_pid
oradebug setospid os_process_pid
oradebug event 10046 trace name context forever, level 12;
-- execute SQL in that process to be traced --
--Stop tracing process with pid = os_process_pid
oradebug event 10046 trace name context off ;
6.使用資料庫觸發器
除了以上方式,也可以結合資料庫級別觸發器,如logon/logoff,針對某一使用者進行跟蹤。
--Start tracing when logon database
create or replace trigger user_logon_t
after logon on database
begin
if USER = 'username' then
execute immediate
'alter session set events ''10046 trace name context forever, level 8''';
end if;
end;
/
-- execute SQL with that user to be traced */
--Stop tracing before logoff database
create or replace trigger user_logoff_t
before logoff on database
begin
if USER = 'username' then
execute immediate
'alter session set events ''10046 trace name context off''';
end if;
end;
/
TKPROF
以上跟蹤會話過程中產生的跟蹤檔案閱讀性不是太友好,很難閱讀。於是Oracle提供了專門的格式化工具tkprof。
tkprof是一個用於分析Oracle跟蹤檔案並且產生一個更加清晰合理的輸出結果的可執行工具,使用tkprof工具使用排序功能格式化輸出,可以使閱讀更加友好。
用法幫助
$ tkprof
Usage: tkprof tracefile outputfile [explain= ] [table= ]
[print= ] [insert= ] [sys= ] [sort= ]
table=schema.tablename Use 'schema.tablename' with 'explain=' option.
explain=user/password Connect to ORACLE and issue EXPLAIN PLAN.
print=integer List only the first 'integer' SQL statements.
aggregate=yes|no
insert=filename List SQL statements and data inside INSERT statements.
sys=no TKPROF does not list SQL statements run as user SYS.
record=filename Record non-recursive statements found in the trace file.
waits=yes|no Record summary for any wait events found in the trace file.
sort=option Set of zero or more of the following sort options:
prscnt number of times parse was called
... ...
使用示例
$ cd $ORACLE_USER_DUMP_DEST
$ tkprof explain=apps/password
trace = prod_ora_3199034.trc
output = prod_ora_3199034.out
TKPROF: Release 9.2.0.6.0 - Production on Mon Feb 25 15:58:26 2013
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
$ ll prod_ora_3199034*
-rw-r--r-- 1 prodora dba 150112 Feb 25 15:58 prod_ora_3199034.out
-rw-r--r-- 1 prodora dba 745495 Feb 25 15:20 prod_ora_3199034.trc
關於tkprof更詳細的說明參見tkprof使用