如何做trace 每一步 每一行
Trace的作用
a) 優化sql
b) 跟蹤系統動作
i. 根據引數追蹤,重現出錯;
ii. 查詢執行緩慢的部分;
Trace檔案是我們可以得到的,系統最明細的執行過程,從執行起始,流經的包,過程或函式,傳入的引數,具體到每句sql的執行計劃,執行時間,執行時間分佈。
藉助trace檔案,我們可以做兩部分事情,一是優化:trace可以具體到每句sql的執行計劃以及執行時間,可以用來查詢哪些sql消耗了最大量的時間;並通過觀察執行過程,判斷優化方式。Trace
Trace的一般流程
獲取Trace檔案路徑
select * from v$parameter t WHERE t.NAME='user_dump_dest'
也可以在command視窗使用如下命令
show parameter user_dump_dest;
啟動trace
對於Form
幫助-》診斷-》跟蹤-》跟蹤約束值和等待事件
系統將會提示trace檔案的位置和檔名稱。
在請求程式定義的介面中,勾選“啟用跟蹤”複選框;另外對於請求來說,無法追蹤其bind的變數值,也就是生成的trace
生成的trace檔名:
SELECT'Request id: '||REQUEST_ID,
'Trace id: '||ORACLE_PROCESS_ID,
'Trace Flag: '||REQ.ENABLE_TRACE,
'Trace Name:'||DEST.VALUE||'/'||LOWER(DBNM.VALUE)||'_ora_'||
ORACLE_PROCESS_ID||'.trc',
'File Name: '||EXECNAME.EXECUTION_FILE_NAME||
EXECNAME.SUBROUTINE_NAME
'Status : '||DECODE(PHASE_CODE,'R','Running')||'-'||
DECODE(STATUS_CODE,'R','Normal'),
'SID Serial: '||SES.SID||','||SES.SERIAL#,
'Module : '||SES.MODULE
FROMFND_CONCURRENT_REQUESTSREQ,
V$SESSION SES,
V$PROCESS PROC,
V$PARAMETER DEST,
V$PARAMETER DBNM,
FND_CONCURRENT_PROGRAMSPROG,
FND_EXECUTABLES EXECNAME
WHEREREQ.REQUEST_ID=&REQUEST
ANDREQ.ORACLE_PROCESS_ID=PROC.SPID(+)
ANDPROC.ADDR=SES.PADDR(+)
ANDDEST.NAME='user_dump_dest'
ANDDBNM.NAME='db_name'
ANDREQ.CONCURRENT_PROGRAM_ID=PROG.CONCURRENT_PROGRAM_ID
ANDREQ.PROGRAM_APPLICATION_ID=PROG.APPLICATION_ID
ANDPROG.APPLICATION_ID=EXECNAME.APPLICATION_ID
ANDPROG.EXECUTABLE_ID=EXECNAME.EXECUTABLE_ID;
對於OAF
首先確認配置檔案”FND:診斷”的值為“是”;
點選頁面右上角“診斷”;
Set Trace Level開始;
Trace with binds and waits儲存;
獲取trace檔名:
記錄左上角生成的trace id tr_id;
進入使用者trace目錄;
執行ls –al *tr_id*;
列出了剛生成的trace檔名;
使用cmd下載trace檔案
Wind+R
Cmd
ftp 10.118.15.217
cd /u01/test/db/tech_st/11.2.0/admin/TEST_tcltest/diag/rdbms/test/TEST/trace
get TEST_vkrm_1626584.trc
--退出
bye
get到的trace檔案在這個命令的目錄下
lcd
分析Trace檔案
常用的trace標記
網上搜集了一部分感覺還算比較全。
MODULE NAME:如果是request的trace文件,這裡會描述請求所執行的併發程式。如果是OAF頁面的trace文件,這裡會指出頁面所使用的Application Module(AM)。
Ex.
a.
*** MODULE NAME:(HCM_REFRESH_SUB_INV) 2010-06-27 09:42:12.406
b.
*** MODULE NAME:(hjit.pobalance.server.PoBalanceAM) 2010-06-27 10:06:37.989
PARSING IN CURSOR:每句執行的sql的起始標記,每出現這樣一個標記,就代表了一句sql開始被執行了。其中有一個比較重要的資訊,是“sqlid”,可以根據這個id找到執行sql的最詳細的描述資訊。
Ex.
PARSING IN CURSOR #6 len=216 dep=1 uid=44 ct=3 lid=44 tim=10801021445054 hv=3104242407 ad='70000007d285380' sqlid='0p5cpqqwhdyr7';
這裡可以用select t.* FROM v$sql t WHERE t.SQL_ID='0p5cpqqwhdyr7'來查詢這句sql的其它明細資訊,比如物理讀取數,快取使用數,發生鎖的次數,等待時間等。
具體每個引數的含義:
Len:sql的長度;
Dep:當前sql語句的遞規深度,如果為0則表示是使用者提交的sql,為1則是由於使用者sql而導致oracle後臺自己執行的sql,為2則是由1級sql繼續誘發的下一級sql。
uid:schema user id of parsing user.
oct:oracle command type.
lid:privilege user id.
tim:timestamp。在oracle9i之前單位是1/100秒,9i則是1/1,000,000秒。利用這個值可以計算一個sql執行了到底多長時間。這個值就是當前行被寫入trace檔案時資料庫v$timer檢視的值。
hv:hash id.
ad:sqltext address,sqltext的地址,跟v$sqlarea和v$sqltext檢視中的address欄位值相等。
parse:parse a statement.解析一個sql
exec:execute a pre-parsed statement.執行已經解析完畢的sql
fetch:fetch rows from a cursor.從遊標中得到資料,通常指select返回記錄
unmap:如果遊標使用了臨時表(temporary table),當遊標關閉的時候將會看到unmap
c:cpu time (100ths of a second in oracle7 ,8 and 9).
e:elapsed time (100ths of a second oracle7, 8. microseconds in oracle 9 onwards).
p:number of physical reads.
cr:number of buffers retrieved for cr reads.
cu:number of buffers retrieved in current mode.
mis:cursor missed in the cache.
r:number of rows processed.
dep:recursive call depth (0 = user sql, >0 = recursive).
og:optimizer goal: 1=all_rows, 2=first_rows, 3=rule, 4=choose
tim:timestamp (large number in 100ths of a second).
stat #<cursor> id=n cnt=0 [pid=0 pos=0 bj=0 p=sort aggregate ]
<cursor>的執行計劃.
<cursor>:cursor which the statistics apply to.
id:line of the explain plan which the row count applies to (從1開始).
cnt:number of rows for this row source.
pid:parent id of this row source.
pos:position in explain plan.
obj:object id of row source (if this is a base object).
op:the row source access operation.
binds #%d:
bind 0: dty=2 mxl=22(22) mal=00 scl=00 pre=00 acflg=03 oacfl2=0 size=24 ffset=0
bfp=02fedb44 bln=22 avl=00 flg=05
value=10
bind:variables bound to a cursor.
bind n:the bind position being bound.
dty:data type.
mxl:maximum length of the bind variable (private max len in paren).
mal:array length.
scl:scale.
pre:precision.
oacflg:special flag indicating bind options
oacflg2:continuation of oacflg
size:amount of memory to be allocated for this chunk
offset:offset into this chunk for this bind buffer
bfp:bind address.
bln:bind buffer length.
avl:actual value length (array length too).
flg:special flag indicating bind status
value:the actual value of the bind variable.
wait #<cursor>: nam="<event name>" ela=0 p1=0 p2=0 p3=0
wait:an event that we waited for.
nam:what was being waited for.
ela:elapsed time for the operation.
p1:p1 for the given wait event.
p2:p2 for the given wait event.
p3:p3 for the given wait event.
begin :1 := fnd_session_management.GETID(:2,:3);end;
Begin呼叫某個過程的標記。
使用tkprof格式化trace檔案
Tkprof工具是Oracle用來格式化trace檔案,便於我們進行分析。
TKPROF的語法如下所示:
tkprof tracefile output_file [sort = parameters] [print=number]
[explain=username/password] [waits=yes|no] [aggregate=yes|no] [insert=filename]
[sys=yes|no] [table=schema.table] [record=filename]
表6-1 命令列選項
變數 |
定義 |
Tracefile |
這就是包含了SQL_TRACE統計資訊的TRACE檔名 |
Output_file |
TKPROF寫入其輸出的檔名 |
print = number |
包含在輸出結果中的語句數目。如果沒有包含這條語句,TKPROF將在輸出中列出所有的語句 |
Explain = username/password |
在TRACE檔案裡對使用者的SQL語句執行EXPLAIN PLAN。這個選項可以建立自己的plan_table,這樣使用者就需要有建立表和建立表所需空間的特權。在TKPROF執行結束時會刪除這個表。確保使用分析游標(執行查詢)的使用者的使用者名稱/密碼,從而確保由正確的使用者進行解釋。檢視Metalink note:199081.1以瞭解更多資訊 |
insert = filename |
這個選項生成指令碼來建立表併為每個所跟蹤的SQL語句儲存TRACE檔案統計 |
record = filename |
這個選項將生成一個儲存使用者所有SQL語句的檔案 |
Sys = yes|no |
這個選項可以在輸出結果裡不顯示請求遞迴SQL語句的使用者(由SYS使用者執行)。預設值為YES。遞迴的SQL通常包括由內部呼叫和表的維護,比如在進行一個插入操作時將擴充套件新增到表中 |
sort = parameters |
有大量的排序選項可用:FCHCPU(獲取的CPU時間)、FCHDSK(獲取的硬碟讀取)、FCHCU和FCHQRY(獲取的記憶體讀取)、FCHROW(取出的行數)、EXEDSK(執行期間的磁碟讀取數);EXECU和EXEQRY(執行期間的記憶體讀取數)、EXEROW(執行時處理的行數)、EXECPU(執行的CPU時間)、PRSCPU(分析CPU)和PRSCNT(分析時間) |
waits=yes/no |
任何等待事件的記錄概要 |
aggregate=yes/no |
如果值為NO,則TKPROF不會組合相同SQL文字的多個使用者 |
table=schema.table |
TKPROF在將執行計劃寫入到輸出檔案之前臨時放置它們的表 |
注意tkprof的結果是不包含繫結變數值的,同時也不包括真正的sql執行順序