Oracle 11g R2效能優化 SQL TRACE--轉發
目錄
正文
作為Oracle官方自帶的一種基本效能診斷工具,SQL Trace可以用來評估當前正在執行的SQL語句的效率,同時為該語句生成統計資訊等,並儲存這些資訊到指定路徑下的跟蹤檔案(trace)當中。SQL Trace會將一條SQL語句或者PL/SQL包執行過程全部輸出到跟蹤檔案(trace)當中,可以通過分析跟蹤檔案(trace)來分析SQL語句的執行效率並進行效能診斷與優化。
通常來說trace檔案的內容不易於理解與閱讀,Oracle官方還提供了工具tkprof
環境準備
- 作業系統(OS):CentOS Linux release 7.5.1804 (Core)
- 資料庫版本(Oracle Database):Oracle Database 11g R2(11.2.0.4.0)
同時配置了示例SCHEMA和解鎖了使用者SCOTT、HR。
回到頂部跟蹤方式
開啟SQL Trace有如下幾種場景與方式:
- 當前會話開啟跟蹤本會話;
- 當前會話開啟跟蹤其他會話;
- 使用DBMS_MONITOR包來開啟跟蹤;
- 根據登入觸發器來開啟跟蹤。
當前會話跟蹤
最簡單的方法是在SQL*PLUS當中執行如下語句:
- 開啟:
-- 配置trace檔案的識別符號便於尋找定位
SYS@dbabd> alter session set tracefile_identifier = dbabd;
-- 開啟當前會話跟蹤
SYS@dbabd> alter session set sql_trace = true;
通過執行以上語句就開啟了當前會話的跟蹤,trace檔案位於 $ORACLE_BASE/diag/rdbms/dbabd/dbabd/trace目錄下:
$ pwd
/data/app/oracle/diag/rdbms/dbabd/dbabd/trace
$ ls *DBABD*
dbabd_ora_27978_DBABD.trc dbabd_ora_27978_DBABD.trm
以上得到trace檔案當中並不包含繫結變數值,也不包含等待事件資訊,如果需要這些資訊,可以使用DBMS_SESSION包來開啟跟蹤,前提是使用者必須有ALTER SESSION
許可權,否則會報ORA-01031: insufficient privileges
錯誤。關於DBMS_SESSION包的用法可以參考官方文件:DBMS_SESSION
如果事先沒有配置trace檔案的識別符號,則可以通過以下語句進行定位:
- 定位:
-- 語句
select tracefile
from v$session s
join v$process p
on p.addr = s.paddr
where s.audsid = USERENV('SESSIONID');
-- 結果
SYS@dbabd> select tracefile
2 from v$session s
3 join v$process p
4 on p.addr = s.paddr
5 where s.audsid = USERENV('SESSIONID');
TRACEFILE
----------------------------------------------------------------------------------------------------
/data/app/oracle/diag/rdbms/dbabd/dbabd/trace/dbabd_ora_27978_DBABD.trc
有時需要確認當前會話是否開啟了跟蹤,可以使用如下語句查詢:
- 查詢:
-- 語句
select s.sql_trace,
s.sql_trace_waits,
s.sql_trace_binds,
traceid,
tracefile
from v$session s
join v$process p
on p.addr = s.paddr
where s.audsid = USERENV('SESSIONID');
-- 結果
SYS@dbabd> select s.sql_trace,
2 s.sql_trace_waits,
3 s.sql_trace_binds,
4 traceid,
5 tracefile
6 from v$session s
7 join v$process p
8 on p.addr = s.paddr
9 where s.audsid = USERENV('SESSIONID');
SQL_TRACE SQL_TRACE_WAITS SQL_TRACE_BINDS TRACEID TRACEFILE
---------- --------------- --------------- ---------- ------------------------------------------------------------
ENABLED FALSE FALSE DBABD /data/app/oracle/diag/rdbms/dbabd/dbabd/trace/dbabd_ora_2797
8_DBABD.trc
如果需要關閉當前會話跟蹤,則執行如下語句:
- 關閉
SYS@dbabd> alter session set sql_trace = false;
回到頂部
其他會話跟蹤
如果是通過當前會話開啟對其他會話的跟蹤,一般都由DBA通過SYS使用者操作,可以使用DBMS_SYSTEM包當中一個儲存過程SET_SQL_TRACE_IN_SESSION,前提是需要獲取到會話的SID和SERIAL#。
- 檢視DBMS_SYSTEM包當中的結構
SYS@dbabd> 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
…………省略…………
PROCEDURE SET_SQL_TRACE_IN_SESSION
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
SID NUMBER IN
SERIAL# NUMBER IN
SQL_TRACE BOOLEAN IN
- 獲取其他會話的SID和SERIAL#
SYS@dbabd> select sid,SERIAL#,username from v$session where username is not null;
SID SERIAL# USERNAME
---------- ---------- ------------------------------------------------------------------------------------------
125 17 SYS
141 45 SCOTT
實際環境當中可能出現同一個使用者有多個會話存在,需要根據v$session檢視當中的其他選項進行判斷,這裡假設只有一個SCOTT使用者會話。
- 開啟對SCOTT使用者會話的跟蹤
SYS@dbabd> begin
2 dbms_system.SET_SQL_TRACE_IN_SESSION(SID => 141,
3 SERIAL# => 45,
4 SQL_TRACE => true
5 );
6 end;
7 /
PL/SQL procedure successfully completed.
或
SYS@dbabd> exec dbms_system.SET_SQL_TRACE_IN_SESSION(141,45,true);
PL/SQL procedure successfully completed.
- 定位跟蹤的trace檔案
SYS@dbabd> select s.sql_trace,
2 s.sql_trace_waits,
3 s.sql_trace_binds,
4 traceid,
5 tracefile
6 from v$session s
7 join v$process p
8 on p.addr = s.paddr
9 where s.sid = 141;
SQL_TRACE SQL_TRACE_WAITS SQL_TRACE_BINDS TRACEID TRACEFILE
---------- --------------- --------------- ---------- ------------------------------------------------------------
ENABLED FALSE FALSE SCOTT /data/app/oracle/diag/rdbms/dbabd/dbabd/trace/dbabd_ora_1014
_SCOTT.trc
- 關閉對SCOTT使用者會話的跟蹤
SYS@dbabd> exec dbms_system.SET_SQL_TRACE_IN_SESSION(141,45,false);
PL/SQL procedure successfully completed.
回到頂部
DBMS_MONITOR包跟蹤
無論是跟蹤當前會話或者其他會話都可以採用DBMS_MONITOR包當中的SESSION_TRACE_ENABLE儲存過程。跟蹤其他會話的前提還是需要獲取到會話的SID和SERIAL#,關閉則使用包當中的SESSION_TRACE_DISABLE儲存過程。
儲存過程SESSION_TRACE_ENABLE引數需求如下,詳細可參考官方文件:SESSION_TRACE_ENABLE Procedure:
PROCEDURE SESSION_TRACE_ENABLE
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
SESSION_ID BINARY_INTEGER IN DEFAULT -- 對應SID
SERIAL_NUM BINARY_INTEGER IN DEFAULT -- 對應SERIAL#
WAITS BOOLEAN IN DEFAULT -- 對應是否加入等待事件跟蹤
BINDS BOOLEAN IN DEFAULT -- 對應是否加入繫結變數跟蹤
PLAN_STAT VARCHAR2 IN DEFAULT -- 對應跟蹤轉儲行資料頻率,取值參考官方文件
儲存過程SESSION_TRACE_DISABLE引數需求如下,詳細可參考官方文件:SESSION_TRACE_DISABLE Procedure:
PROCEDURE SESSION_TRACE_DISABLE
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
SESSION_ID BINARY_INTEGER IN DEFAULT
SERIAL_NUM BINARY_INTEGER IN DEFAULT
從以上兩個儲存過程所需引數來看,如果是跟蹤當前會話的話可以省略SESSION_ID和SERIAL_NUM這兩個引數,具體的開啟和關閉語句可以參考其他會話跟蹤當中的DBMS_SYSTEM包使用方法。
回到頂部當前資料庫跟蹤
使用DBMS_MONITOR包還可以用來開啟整個資料庫的跟蹤,但是這會造成trace檔案異常龐大,不便於定位具體問題,而且也會造成一定的效能損失,所以通常不建議開啟。
採用SQL語句方式:
-- 開啟
SYS@dbabd> alter system set sql_trace = true;
-- 關閉
SYS@dbabd> alter system set sql_trace = false;
採用DBMS_MONITOR包方式,主要使用DATABASE_TRACE_ENABLE和DATABASE_TRACE_DISABLE兩個儲存過程:
PROCEDURE DATABASE_TRACE_ENABLE
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
WAITS BOOLEAN IN DEFAULT
BINDS BOOLEAN IN DEFAULT
INSTANCE_NAME VARCHAR2 IN DEFAULT
PLAN_STAT VARCHAR2 IN DEFAULT
PROCEDURE DATABASE_TRACE_DISABLE
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
INSTANCE_NAME VARCHAR2 IN DEFAULT
-- 開啟
SYS@dbabd> exec dbms_monitor.DATABASE_TRACE_ENABLE(true,true,'dbabd','all_executions');
-- 關閉
SYS@dbabd> exec dbms_monitor.DATABASE_TRACE_DISABLE('dbabd');
回到頂部
採用登入觸發器跟蹤
可以通過建立登入觸發器來跟蹤某個使用者的SQL執行效率情況,登入觸發器會在會話初始化的時候去執行,觸發器可以根據指定條件是否對這次會話開啟跟蹤,以下登入觸發器是以SCOTT使用者為例,為SCOTT使用者登入的所有會話設定合適的trace檔案識別符號並開啟跟蹤。
-- 建立觸發器SCOTT_LOGIN_TRACE語句
create or replace trigger scott_login_trace
after logon on database
begin
if user = 'SCOTT'
then
execute immediate 'alter session set tracefile_identifier = SCOTT';
dbms_session.session_trace_enable(waits => true, binds => true, plan_stat => 'all_executions');
end if;
end;
/
使用SYS使用者進行建立:
SYS@dbabd> create or replace trigger scott_login_trace
2 after logon on database
3 begin
4 if user = 'SCOTT'
5 then
6 execute immediate 'alter session set tracefile_identifier = SCOTT';
7 dbms_session.session_trace_enable(waits => true,
8 binds => true,
9 plan_stat => 'all_executions'
10 );
11 end if;
12 end;
13 /
Trigger created.
檢視觸發器狀態:
SYS@dbabd> select owner,trigger_name,status,trigger_body from all_triggers where owner = 'SYS' and trigger_name = 'SCOTT_LOGIN_TRACE';
OWNER TRIGGER_NAME STATUS TRIGGER_BODY
---------- -------------------- ---------- --------------------------------------------------------------------------------
SYS SCOTT_LOGIN_TRACE ENABLED begin
if user = 'SCOTT'
then
execute immediate 'alter session set tracefile_identifier = SCOTT';
dbms_session.session_trace_enable(waits => true, binds => true, plan_stat => 'all_executions');
end if;
end;
建立完觸發器之後,SCOTT使用者只要一登入就會預設開啟跟蹤。
回到頂部總結
以上梳理了常見的開啟SQL TRACE的幾種方式,但是原始的trace檔案可讀性比較差,通常不會直接去讀取,而是通過工具tkprof進行格式化之後進行閱讀,關於tkprof的使用可以參考我另一篇博文:Oracle 11g R2效能優化 tkprof
回到頂部參考
https://docs.oracle.com/cd/E11882_01/server.112/e41573/sqltrace.htm#PFGRF010
https://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_sessio.htm#ARPLS054
https://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_monitor.htm#ARPLS091
☆〖本人水平有限,文中如有錯誤還請留言批評指正!〗☆