Oracle時間資訊特性

jss001發表於2009-02-15
在監控、診斷、處理資料庫效能問題的時候,時間資訊往往是非常重要的判斷依據。有時候可能我們會使用一些比例來判斷效能,但是使用比例而不使用時間往往會將我們帶向錯誤的方向。在Oracle9i的第一版中關於時間的資訊被進行了增強,提供了更多更有益的時間資訊。除了9i的外貌發生了變化,在一些並沒有被我們注意或者不為人知得一些v$檢視的相關欄位也發生了變化。這裡提到的主要是他們發生了那些改變以及對DBA有什麼幫助。這裡也列出了零星的一些Oracle內部的未公開的資訊。

Second 1 秒
Centi-second 1/100 百分之一秒 釐秒
Milli Second 1/1000 千分之一秒 毫秒
Micro Second 1/1.000.000 微妙
Nano Second 1/1.000.000.000 納秒

在以前的版本中,Oracle的時間計量單位是釐秒,使用釐秒最顯而易見的問題就是可能有些操作是小於釐秒的。看上去這似乎不太常見,但是實際上在作業系統上很多操作都是以微妙作為單位的,這意味著操作的起始和終止在不到釐秒就完成了,從釐秒級看就好像沒有發生一樣,因為持續時間近似為0。而有時候操作的持續時間不到釐秒,但是起始和終止發生在兩個相連的釐秒,所以操作時間不到釐秒但是卻被記錄為釐秒,造成時間記錄的不準確。
在Oracle9i之前,最小的時間單位仍然是釐秒,這可以在跟蹤檔案、v$system_event和v$session_event中的超時欄位看到。在9i之前,是不能在聯機狀態看到sql語句的執行(cpu消耗)時間和持續時間的,也不能看到一條Sql語句在等待著什麼,實際上只有一種方法可以得到這些資訊,就是透過啟用10046 trace level 12的跟蹤事件。這樣做也會帶來下面的一些問題:
1. 生成程式跟蹤檔案帶來很高的效能開銷
2. 如果有太多用於幫助調優的sql語句執行,將會產生大量的磁碟/檔案空間需求。

在oracle9i第一版中
在oracle9i第一版中的持續時間以微妙作為時間單位,這能夠顯示出Oracle真正花費的時間。超時仍然以微妙作為計時單位。一些檢視被擴充套件以便記錄微妙資料。所有的時間資訊由初始化引數timed_statistics 決定。

一些檢視的改變:
V$SQLAREA:
兩個欄位被加入到V$SQLAREA中,分別是CPU_TIME 和ELAPSED_TIME。兩個欄位都被設定為微妙級。然而,在這裡可能會s看到一個有趣的現象:
Select cpu_time, elapsed_time
From v$sqlarea
Order by 2
CPU_TIME ELAPSED_TIME
---------- ------------
230000 174567
260000 258803
260000 271808
首先:三行中的第二行顯示出了持續時間小於cpu執行時間,實際的情況是cpu欄位記錄單位是微妙級,但是資料被進位保留到了釐秒級。

Sql 語句的等待時間等於ELAPSED_TIME減去CPU_TIME,但是很難看到精確的等待時間。在V$SYSTEM_EVENT 檢視中能夠看到資料庫例項級的等待時間(並不是每條Sql語句的),但是看不到發生在作業系統上(cpu等待、記憶體的等待)的等待時間s。

X$KSQST的改變 (對應檢視V$ENQUEUE_STAT)

基礎表X$KSQST主要顯示關於系統中佇列的資訊。在9i之前只能提供佇列型別的get和wait數。一個佇列有兩種特徵和兩個標識組成(id1 and id2)。例如一個叫做TX佇列,表示一個事務佇列。從Oracle9i開始不但能夠看到gets 和waits,而且等待的時間和得不到佇列(中斷或者超時)的失敗次數都可以看到。

X$KSQST
KSQSTWTIM NUMBER 以微妙作為單位

然而這裡仍不能將佇列等待與Sql語句關聯,也不能夠得到等待佇列的Sql語句到底等待了多久。下面的一個新的檢視v$enqueue_stat 將提供關於佇列得更多資訊:

V$ENQUEUE_STAT
INST_ID NUMBER
EQ_TYPE VARCHAR2
TOTAL_REQ# NUMBER
TOTAL_WAIT# NUMBER
SUCC_REQ# NUMBER
FAILED_REQ# NUMBER
CUM_WAIT_TIME NUMBER

V$SYSSTAT的改變
實際這個檢視並沒有什麼改變,關於時間的資訊仍然在釐秒級。

V$SYSSTAT
CPU used by this session 釐秒
Parse time cpu 釐秒
Parse time 釐秒
Recursive cpu usage 釐秒
當從不同資源中比較資料時應該注意。

V$WAITSTAT的改變
這個檢視顯示了發生在塊級的buffer busy waits的細目描述,等待時間的單位在微妙級。

V$WAITSTAT
TIME NUMBER 釐秒單位
這裡無法透過檢視中出現的等待找到對應的sql語句。

V$FILESTAT的改變
在這個檢視中現在分成了單次塊讀取和累計塊讀取,這種分法更合理。

V$FILESTAT
MAXIORTM NUMBER 釐秒級的最大讀取時間
MAXIOWTM NUMBER 釐秒級的最大寫入時間
SINGLEBLKRDS NUMBER 單次塊讀取塊數
SINGLEBLKRDTIM NUMBER 釐秒級的累計單次塊讀取時間
這個檢視也不能找到相關的Sql語句,使用dbms_system.kcfrms()過程可以重設最大讀、寫時間,設定更準確的取樣間隔。

V$SESSION_EVENT的改變
這個檢視現在已經可以捕捉到微妙級的等待事件的持續時間了。它可以以微妙或者釐秒方式顯示等待時間,因為這些改變,等待事件變得更加精確(等待時間以微妙方式捕捉,然後轉換為釐秒方式)

V$SESSION_EVENT
TIME_WAITED_MICRO NUMBER 以微妙級等待的時間
TIME_WAITED NUMBER 微妙級的等待時間 / 10000
MAX_WAIT NUMBER 釐秒級的最大等待時間

當然,這個檢視也不能找到相關的Sql語句。
一個被大多數DBA所感興趣的欄位是MAX_WAIT 欄位,這個欄位顯示了一個事件的最大等待時間。這個資訊只要會話一登陸就生效,將顯示一個會話整個生命期中的最大等待時間。使用 dbms_system.kcfrms() 過程可以重置最大的值,以便讓這個欄位顯示與測量週期更緊密的值。

V$SYSTEM_EVENT的改變
這個檢視最主要的變化是增加了TIME_WAITED_MICRO欄位,它以微妙為單位顯示了持續的時間。.另外TIME_WAITED 也更加精確,,因為它來自於TIME_WAITED_MICRO的值。

V$SYSTEM_EVENT
TIME_WAITED_MICRO NUMBER 持續的等待時間(微妙)
TIME_WAITED NUMBER 從time_waited_micro取值,以釐秒為單位

SQL TRACE
透過在會話級設定事件‘10046 trace name context level 12, forever’可以看到下面的跟蹤資訊。
PARSING IN CURSOR #1 len=29 dep=0 uid=5 oct=3 lid=5 tim=1006862415399006 hv=4384
51932 ad='84b05c04'
select count(*) from tab, tab
END OF STMT
PARSE #1:c=10000,e=11334,p=0,cr=4,cu=0,mis=1,r=0,dep=0,og=4,tim=1006862415398976
BINDS #1:
EXEC #1:c=0,e=587,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1006862415399931
WAIT #1: nam='SQL*Net message to client' ela= 10 p1=1650815232 p2=1 p3=0
FETCH #1:c=2500000,e=2526458,p=0,cr=149542,cu=0,mis=0,r=1,dep=0,og=4,tim=1006862
417926777
WAIT #1: nam='SQL*Net message from client' ela= 1004 p1=1650815232 p2=1 p3=0
FETCH #1:c=0,e=6,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,tim=1006862417928426
WAIT #1: nam='SQL*Net message to client' ela= 7 p1=1650815232 p2=1 p3=0
WAIT #1: nam='SQL*Net message from client' ela= 3636276 p1=1650815232 p2=1 p3=0
注意:時間都是微妙級的,但是這裡仍然有一些很有意思的地方:

1. tim= 明顯是微妙級的,這個tim 域給出了一個時間快照
2. e= 和 ela= 也是微妙級的,這兩個域表示持續的事件
3. 比較有趣的是c=. 看上去好像是微妙級的,但是實際上是釐秒級的資料乘上了10000, 域c 表示cpu的消耗

v$latch, / v$latch_parent / v$latch_children 的改變:
在Oracle9i主要的改變是增加了wait_time欄位。因此現在鎖存器競爭更容易檢測了,而在Oracle9i以前,只能透過察看sleeps次數來判斷。在v$latch中主要相關的欄位包括:
V$LATCH
NAME VARCHAR(64) 鎖存器名稱.
SLEEPS NUMBER 鎖存器由於忙而產生的sleep次數
SLEEP1..11 NUMBER 顯示了sleep的分佈情況
WAIT_TIME NUMBER 微妙級的等待時間

在Orace9i以前與v$latch的 ‘latch free’等待事件的SLEEPS欄位對應的是v$system_event的TOTAL_WAITS欄位:
select event, total_waits, time_waited
from v$system_event
where event = 'latch free'

select name, trunc(sleeps*100/ total, 2) "Perc of Sleeps"
from v$latch, (select decode(sum(sleeps), 0, 1, sum(sleeps)) total from v$latch)
where sleeps != 0

有很多sleeps的鎖存器會顯示為v$system_event的大量等待時間。在Oracle9i由於在v$latch中有了WAIT_TIME欄位,所以提供了更準確的資訊:
select name, trunc(wait_time*100/time_waited, 2) "Perc. of Time Waited"
from v$latch, (select time_waited from v$system_event where event = 'latch free')
where wait_time != 0
order by 2

還有那些沒有改變?
其他與時間相關的資訊都沒有改變。在V$SYSSTAT中象 ‘CPU used by this session’, ‘parse cpu time’ and ‘recursive cpu usage’等事件仍然表示為釐秒。

Oracle沒有改變這些統計資訊的單位是因為這些資訊可能會影響著一些依賴於他們的應用或者指令碼。

Oracle的Precise/Indepth
在 Oracle9i中由於使用了微妙做為單位,所以持續時間已經變得更加準確,但是仍然不能看到在一個特定的時間範圍內的每個sql語句的資源消耗。瞭解每個sql語句的資源消耗能夠幫助你確定那個sql語句是你首先應該調優的。使用Oracle的Precise/Indepth,透過不斷的監視Oracle的環境,收集用於效能分析的資料,就能夠看到每條Sql語句的資源消耗情況。這些資源消耗情況最終被細分為:

Using CPU
CPU wait
I/O wait
Memory wait
Other host wait
Table lock wait
Row lock wait
Shared pool wait
Buffer wait
Rollback segment wait
Redo log buffer wait
Log switch and clear wait
Internal lock wait
Background process wait
Parallel query sync. Wait
Parallel query server wait
Other wait[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/18921899/viewspace-1017384/,如需轉載,請註明出處,否則將追究法律責任。

相關文章