【DB筆試面試686】在Oracle中,SQL_TRACE是什麼?診斷事件是什麼?
- 2019 年 11 月 14 日
- 筆記
♣
題目部分
在Oracle中,SQL_TRACE是什麼?診斷事件是什麼?
♣
答案部分
(一)SQL_TRACE
SQL_TRACE是Oracle提供的用於進行SQL跟蹤的手段,是強有力的輔助診斷工具。在日常的數據庫問題診斷和解決中,SQL_TRACE是非常常用的方法。可以設置SQL_TRACE為TRUE,但是一般不推薦在全局指定為TRUE,只建議在會話級別指定。若在全局設定則對性能會造成較大影響。
(二)診斷事件
Oracle為數據庫提供了多種的診斷工具,診斷事件(Event)是其中一種非常實用的方法,它能使DBA可以方便地轉儲數據庫各種結構及跟蹤特定事件的發生過程。
通過如下的腳本可以獲取所有的診斷事件列表:
1DECLARE 2 ERR_MSG VARCHAR2(32767); 3BEGIN 4 DBMS_OUTPUT.ENABLE(''); 5 FOR ERR_NUM IN 10000 .. 10999 LOOP 6 ERR_MSG := SQLERRM(-ERR_NUM); 7 IF ERR_MSG NOT LIKE '%Message ' || ERR_NUM || ' not found%' THEN 8 DBMS_OUTPUT.PUT_LINE(ERR_MSG); 9 END IF; 10 END LOOP; 11END; 12/
在Linux系統下診斷事件的消息文件放在目錄:$ORACLE_HOME/rdbms/mesg/oraus.msg。oraus.msg文件屬於文本文件,可以直接打開查看。
診斷事件可以像普通的ORA錯誤一樣採用oerr命令來查詢,如下所示:
1[oracle@orclalhr ~]$ oerr ora 10046 210046, 00000, "enable SQL statement timing" 3// *Cause: 4// *Action: 5[oracle@orclalhr ~]$ oerr ora 10053 610053, 00000, "CBO Enable optimizer trace" 7// *Cause: 8// *Action: 9[oracle@orclalhr ~]$ oerr ora 10704 1010704, 00000, "Print out information about what enqueues are being obtained" 11// *Cause: When enabled, prints out arguments to calls to ksqcmi and 12// ksqlrl and the return values. 13// *Action: Level indicates details: 14// Level: 1-4: print out basic info for ksqlrl, ksqcmi 15// 5-9: also print out stuff in callbacks: ksqlac, ksqlop 16// 10+: also print out time for each line
設置診斷事件有兩種方法,一種是在pfile參數文件中設置事件,這樣數據庫在OPEN後,將影響到所有的會話。設置格式如下:
1event="eventnumber trace name eventname [forever,] [level levelnumber] : ......."
通過冒號(:)符號,可以連續設置多個事件,也可以通過連續使用event來設置多個事件。如:
1event = "10248 trace name context forever, level 10:10249 trace name context forever, level 10"
或者分開寫,如:
1event="10248 trace name context forever, level 10" 2event="10249 trace name context forever, level 10"
另一種方法是在會話過程中使用ALTER SESSION SET EVENTS命令,只對當前會話有影響。設置格式如下:
1ALTER SESSION|SYSTEM SET EVENTS '[eventnumber|immediate] trace name eventname [forever] [, level levelnumber] : .......'
通過英文冒號(:)符號,可以連續設置多個事件,也可以通過連續使用ALTER SESSION SET EVENTS來設置多個事件,如:
1ALTER SYSTEM SET 2 EVENTS='10325 trace name context forever, level 10','10015 trace name context forever, level 1' 3 COMMENT='Debug tracing of control and rollback';
或:
1ALTER SYSTEM SET EVENTS='10325 trace name context forever, level 10:10015 trace name context forever, level 1';
格式說明:
l eventnumber指觸發dump的事件號,事件號可以是Oracle錯誤號(出現相應錯誤時跟蹤指定的事件)或Oralce內部事件號,內部事件號在10000到10999之間,不能與immediate關鍵字同用。
l immediate關鍵字表示命令發出後,立即將指定的結構dump到跟蹤文件中,這個關鍵字只用在ALTER SESSION語句中,並且不能與eventnumber、forever關鍵字同用。
l trace name是關鍵詞,trace name位於第二、三項,除它們外的其它限定詞是供Oracle內部開發組用的。
l eventname指事件名稱,即要進行dump的實際結構名。若eventname為context,則指根據內部事件號進行跟蹤。
l forever關鍵字表示事件在實例或會話的周期內保持有效狀態,不能與immediate同用。
l level為事件級別關鍵字。但在dump錯誤棧(errorstack)時不存在級別。level通常位於1-10之間(10046有時用到12),10意味着轉儲事件所有的信息。例如當轉儲控制文件時,level 1表示轉儲控制文件頭,而level 10表明轉儲控制文件全部內容。
l levelnumber表示事件級別號,一般從1到10,1表示只dump結構頭部信息,10表示dump結構的所有信息。
l 轉儲所生成的trace文件在user_dump_dest初始化參數指定的位置。
l 移除所有的診斷事件(Event):
1ALTER SYSTEM RESET EVENT SCOPE=SPFILE SID='*' ;
如果設置了診斷事件(Event),那麼如何知道在系統中設置了哪些診斷事件(Event)呢?如果事件是在pfile文件中設置的,那麼可以用「SHOW PARAMETER EVENT」來查看。如果是通過「ALTER SYSTEM|SESSION」來設置的,那麼可以使用如下的SQL來查看:
1SET SERVEROUTPUT ON SIZE 1000000 2DECLARE 3 EVENT_LEVEL NUMBER; 4BEGIN 5 FOR I IN 10000 .. 99999 LOOP 6 SYS.DBMS_SYSTEM.READ_EV(I, EVENT_LEVEL); 7 IF (EVENT_LEVEL > 0) THEN 8 DBMS_OUTPUT.PUT_LINE('Event ' || TO_CHAR(I) || ' set at level ' ||TO_CHAR(EVENT_LEVEL)); 9 END IF; 10 END LOOP; 11END; 12/ 13
但是,10046和10053事件不能通過這種方式查詢,只能通過oradebug來查詢,如下:
1SYS@orclasm > oradebug setmypid 2SYS@orclasm > oradebug eventdump system 3SYS@orclasm > oradebug eventdump session
設置診斷事件需要注意的是,即可以使用「ALTER SYSTEM EVENTS」,也可以使用「ALTER SYSTEM EVENT」,它們的區別在如下2點:
① EVENTS可以動態修改,可以使用「ALTER SESSION」或「ALTER SYSTEM」設置,隻影響內存不影響參數文件
② EVENT不能動態修改,只能使用「ALTER SYSTEM」或在參數文件里設置,必須重啟庫方可生效
另外,「ALTER SYSTEM」會記錄到告警日誌中,「ALTER SESSION」不會記錄在告警日誌中。
本文選自《Oracle程序員面試筆試寶典》,作者:小麥苗