一、跟蹤文件是干什么用的?
跟蹤文件中包含了大量而詳細的診斷和調試信息。通過對跟蹤文件的解讀和分析,我們可以定位問題、分析問題和解決問題。從跟蹤文件的產生的來源來看,跟蹤文件又可以分為兩類:一類是數據庫的操作人員有意生成的;另一類則是由於出現了異常錯誤,由數據庫自動生成的。對於后一類,只對Oracle內部的技術支持人員是有用的,但對於我們,則多半看不懂。前一類,則是我們經常用到的,幫助我們分析、調整和優化應用性能,處理並解決問題。
二、跟蹤文件是如何命名的?
一個跟蹤文件的名字一般由以下幾部分組成:
ORACLE_SID
固定字符"ora"
服務器的進程ID號
文件后綴名 .trc
前三個部分之間以下划線連接。
如下例:
orcl_ora_6210.trc
其中“orcl" 是本環境下數據庫的SID,"6210"為產生該跟蹤文件會話所使用的服務器進程ID號。如何知道我的ORACLE_SID和會話所使用的服務器進程ID呢?后面會詳細講到。
上面說到的跟蹤文件的命名規則適用於我們前面說的第一類跟蹤文件,即數據庫操作人員有意生成的跟蹤文件。如果是第二類跟蹤文件,則命名上稍有變化。這類跟蹤文件將固定字符"ora"改為了ORACLE后台進程名的縮寫。如下例所示:
orcl_lgwr_30019.trc
orcl_dbw0_2664.trc
三、跟蹤文件存放在哪里?
跟蹤文件存放的位置根據數據庫版本的不同,位置也是不同的。下面以10g 和11g分別說明。
10g
通常,我們在安裝數據庫時,會設定一個環境變量$ORACLE_BASE(注意,是BASE,不是HOME),該變量中指定了ORACLE軟件安裝的主目錄。假設我們設定的目錄為”/oracle/app/oracle“,那么跟蹤文件會放到以下這幾個目錄中:
/oracle/app/oracle/admin/orcl/bdump 該目錄用來存儲ORACLE后台進程生成的輸出文件。數據庫自動生成的跟蹤文件默認是存儲在這里,另外,我們經常提到的報警日志,也是放在這里的。
/oracle/app/oracle/admin/orcl/cdump 該目錄用來存儲內核進程產生的輸出文件
/oracle/app/oracle/admin/orcl/udump 該目錄用來存儲用戶生成的輸出文件。我們有意生成的跟蹤文件默認就是存儲在這里。
以上是說的是默認情況下,如果數據庫的管理員改變了這個設置的話,我們更保險的方法是查詢相關參數來確定,查詢方法如下:
通過SQLPLUS以管理員身份登錄,輸入 show parameter dump_dest 並回車。例如:
SQL> show parameter dump_dest
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
background_dump_dest string /oracle/app/oracle/admin/orcl/ bdump
core_dump_dest string /oracle/app/oracle/admin/orcl/cdump
user_dump_dest string /oracle/app/oracle/admin/orcl/ udump
此外,這些設置,在參數文件中也有記錄。通過查詢參數文件亦可獲得。
11g
11g中引入了一個新的功能,稱為自動診斷知識庫(Automatic Diagnostic Repository 縮寫為ADR)。它是所有診斷信息的的中心存儲點,它包括各種轉儲文件、跟蹤文件、日志和健康狀況監視報表。所有實例(RDBMS實例和ASM實例)都在ADR中創建有自己的目錄結構。
ADR的位置是由參數DIAGNOSTIC_DEST來指定,默認位置同$ORACLE_BASE。其結構如下:
ORACLE_BASE/diag/database_name/instance_name
假設我們設定的$ORACLE_BASE仍為”/oracle/app/oracle“,數據庫名稱和實例名稱均為”orcl",則實際的目錄結構如下:
/oracle/app/oracle/diag/orcl/orcl
這個位置,也被稱為本例中數據庫實例ORCL的ADR_HOME。
在這個目錄下,還會發現有一個子目錄,名為trace,其下集中存儲了數據庫后台進程和用戶主動生成的跟蹤文件以及報警日志。
但這也是默認情況下,我們通過查詢v$diag_info視圖,就可以獲得實際的位置。如下所示:
SELECT * FROM V$DIAG_INFO;
INST_ID NAME VALUE ------- --------------------- ------------------------------------------------------------- 1 Diag Enabled TRUE 1 ADR Base /u01/oracle 1 ADR Home /u01/oracle/diag/rdbms/orclbi/orclbi 1 Diag Trace /u01/oracle/diag/rdbms/orclbi/orclbi/trace 1 Diag Alert /u01/oracle/diag/rdbms/orclbi/orclbi/alert 1 Diag Incident /u01/oracle/diag/rdbms/orclbi/orclbi/incident 1 Diag Cdump /u01/oracle/diag/rdbms/orclbi/orclbi/cdump 1 Health Monitor /u01/oracle/diag/rdbms/orclbi/orclbi/hm
四、如何找到特定的跟蹤文件?
通過上面的介紹,我們已經知道了跟蹤文件是如何命名的,存儲到了什么地方。但對於一個繁忙的系統,在同一個目錄下,可能會在相近的時間內生成多個跟蹤文件,那么如何才能找到我們想要的那個跟蹤文件呢。核心就是要確定我們所使用的服務器進程ID號。有了這個ID號,我們就可以確定地知道哪個跟蹤文件才是我們想要的。下面介紹一下如何查詢服務器進程ID號。
當前正在運行的服務器進程ID號,都存儲在v$process視圖中。但由於該視圖中提供的信息有限,大多數的時候,我們很難定位到底哪個服務器進程ID(SPID)才是我們要找的。 比如下面的這個輸出,基本是一樣的。
SQL> select addr,spid,username,terminal,program from v$process;
ADDR SPID USERNAME TERMINAL PROGRAM
----------------------- ------------ --------------- ------------------------------ ------------------------------------------------
000000007FE6D7A8 2447 oracle UNKNOWN oracle@localhost.localdomain (MMNL)
000000007FE6DFA0 2449 oracle UNKNOWN oracle@localhost.localdomain (D000)
000000007FE6E798 2451 oracle UNKNOWN oracle@localhost.localdomain (S000)
000000007FE6EF90 2453 oracle pts/1 oracle@localhost.localdomain (TNS V1-V3)
000000007FE6F788 2455 oracle UNKNOWN oracle@localhost.localdomain (ARC0)
000000007FE6FF80 2457 oracle UNKNOWN oracle@localhost.localdomain (ARC1)
000000007FE70778 2459 oracle UNKNOWN oracle@localhost.localdomain (CTWR)
000000007FE70F70 2461 oracle UNKNOWN oracle@localhost.localdomain (QMNC)
000000007FE71768 5703 oracle pts/2 oracle@localhost.localdomain (TNS V1-V3)
000000007FE71F60 5839 oracle UNKNOWN oracle@localhost.localdomain
000000007FE73F40 2475 oracle UNKNOWN oracle@localhost.localdomain (q000)
這時,我們就借助v$session視圖,即通過會話找服務器進程(一個進程可以有多個會話,但一個會話,只能屬於一個進程)。前面說過,跟蹤文件分為兩類,我們需要的是我們主動生成的跟蹤文件。即然是我們主動生成的,那一定是在我們當前的會話中產生。因此,我們可以利用以下語句找到我們當前會話所屬的服務器進程ID(SPID)。
SQL> select a.spid from v$process a,v$session b where b.sid=sys_context('userenv','sid') and a.addr=b.paddr;
SPID
------------
5922
上面語句中的 sys_context('userenv','sid') 是利用系統內置的函數來取當前的會話ID(SID),這個函數也可以用 userenv('sid') 來代替,結果是一樣的。只不過ORACLE建議使用前者。因為后面這個函數只是出於保持版本的兼容性而保留下來的,但說不定什么時候,這個函數就會在更新的版本中取消了。
有了這個SPID,我們就可以去相應的跟蹤文件的存放位置,去查找在當前時間產生的,文件名中含有”5922“的跟蹤文件了。
另外,我們也可以使用下面這個SQL語句,在當前會話中直接查詢而獲得跟蹤文件的絕對路徑和名字。
select c.value || '/' || d.instance_name || '_ora_' || a.spid || '.trc' trace
from v$process a, v$session b, v$parameter c, v$instance d
where a.ADDR = b.PADDR
and b.SID = sys_context('userenv','sid')
and c.NAME = 'user_dump_dest' ;