statspack報告分析摘錄

hunterjoy發表於2008-06-24

取自 作者: 

今天晚上看了這篇文章,覺得不錯,特儲存下來,以便今後參考,謝謝上面的作者。

(1) 調整的先後次序 

1. Tune the design. -- Application designers 

2. Tune the application. -- Application developers 

3. Tune memory. 

4. Tune I/O. 

5. Tune contention. 

6. Tune the operating system. 



Statspack分析報告詳解: 

statspack 輸出結果中必須檢視的十項內容 

  1、負載間檔(Load profile) 
  2、例項效率點選率(Instance efficiency hit ratios) 
  3、首要的5個等待事件(Top 5 wait events) 
  4、等待事件(Wait events) 
  5、閂鎖等待 
  6、首要的SQL(Top sql) 
  7、例項活動(Instance activity) 
  8、檔案I/O(File I/O) 
  9、記憶體分配(Memory allocation) 
  10、緩衝區等待(Buffer waits



1.報表頭資訊
資料庫例項相關資訊,包括資料庫名稱、ID、版本號及主機等資訊。

STATSPACK report for 
DB Name DB Id Instance Inst Num Release Cluster Host 
------------ ----------- ------------ -------- ----------- ------- ------------ 
BLISSDB 4196236801 blissdb 1 9.2.0.4.0 NO BLISS 
Snap Id Snap Time Sessions Curs/Sess Comment 
------- ------------------ -------- --------- ------------------- 
Begin Snap: 4 23-6月 -05 17:43:32 10 3.3 
End Snap: 5 23-6月 -05 18:01:32 12 6.1 
Elapsed: 18.00 (mins) 
Cache Sizes (end) 
~~~~~~~~~~~~~~~~~ 
Buffer Cache: 24M Std Block Size: 8K 
Shared Pool Size: 48M Log Buffer: 512K 

2.負載間檔
該部分提供每秒和每個事物的統計資訊,是監控系統吞吐量和負載變化的重要部分。
Load Profile 
~~~~~~~~~~~~ 
Per Second Per Transaction
--------------- ---------------
Redo size: 431,200.16 18,627,847.04z
Logical reads: 4,150.76 179,312.72
Block changes: 2,252.52 97,309.00
Physical reads: 23.93 1,033.56
Physical writes: 68.08 2,941.04
User calls: 0.96 41.36
Parses: 1.12 48.44
Hard parses: 0.04 1.92
Sorts: 0.77 33.28
Logons: 0.00 0.20
Executes: 2.36 102.12
Transactions: 0.02 

Redo size:每秒產生的重做日誌大小(單位位元組),可標誌資料變更頻率, 資料庫任務的繁重與否。本例中平均每秒產生了430K左右的重做,每個事務品均產生了18M的重做。
Logical reads:平次每秒產生的邏輯讀,單位是block。
block changes:每秒block變化數量,資料庫事物帶來改變的塊數量。
Physical reads:平均每秒資料庫從磁碟讀取的block數。
Logical reads和Physical reads比較:大約有0.55%的邏輯讀導致了物理I/O,平均每個事務執行了大約18萬個邏輯讀,在這個例子中,有一些大的事務被執行,因此很高的讀取數目是可以接受的。
Physical writes:平均每秒資料庫寫磁碟的block數。
User calls:每秒使用者call次數。
Parses和Hard parses:每秒大約1.12個解析,其中有4%為硬解析,系統每25秒分析一些SQL,都還不錯。對於最佳化好的系統,執行了好幾天後,這一列應該達到0,所有的sql在一段時間後都應該在共享池中。
Sorts:每秒產生的排序次數。
Executes:每秒執行次數。
Transactions:每秒產生的事務數,反映資料庫任務繁重與否。
% Blocks changed per Read: 54.27 Recursive Call %: 86.94
Rollback per transaction %: 12.00 Rows per Sort: 32.59 

% Blocks changed per Read:說明46%的邏輯讀是用於那些只讀的而不是可修改的塊,該系統只更新54%的塊。
Rollback per transaction %:事務回滾的百分比。計算公式為:Round(User rollbacks / (user commits + user rollbacks) ,4)* 100%。本例中每8.33個事務導致一個回滾。如果回滾率過高,可能說明資料庫經歷了太多的無效操作。過多的回滾可能還會帶來Undo Block的競爭。
3.例項命中率
該部分可以提前找出ORACLE潛在將要發生的效能問題,很重要。
Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Buffer Nowait %: 100.00 Redo NoWait %: 100.00
Buffer Hit %: 99.42 In-memory Sort %: 100.00
Library Hit %: 98.11 Soft Parse %: 96.04
Execute to Parse %: 52.57 Latch Hit %: 100.00
Parse CPU to Parse Elapsd %: 11.40 % Non-Parse CPU: 99.55
Buffer Nowait %:在緩衝區中獲取Buffer的未等待比率,Buffer Nowait<99%說明,有可能是有熱塊(查詢x$bh的 tch和v$latch_children的cache buffers chains)。
Redo NoWait %:在Redo緩衝區獲取Buffer的未等待比率。
Buffer Hit %:資料塊在資料緩衝區中的命中率,通常應在90%以上,否則,小於95%,需要調整重要的引數,小於90%可能是要加db_cache_size,但是大量的非選擇的索引也會造成該值很高(大量的db file sequential read)。如果一個經常訪問的列上的索引被刪除,可能會造成buffer hit 顯著下降。如果增加了索引,但是它影響了ORACLE正確的選擇表連線時的驅動順序,那麼可能會導致buffer hit 顯著增高。如果命中率變化幅度很大,說明需要改變SQL模式。
In-memory Sort %:在記憶體中的排序率。
Library Hit %:主要代表sql在共享區的命中率,通常在95%以上,否則需要要考慮加大共享池,繫結變數,修改cursor_sharing等引數。
Soft Parse %:近似看作sql在共享區的命中率,小於<95%,需要考慮到繫結,如果低於80%,那麼就可能sql基本沒有被重用。
Execute to Parse %:一個語句執行和分析了多少次的度量。在一個分析,然後執行語句,且再也不在同一個會話中執行它的系統中,這個比值為0。計算公式為:Execute to Parse =100 * (1 - Parses/Executions)。所以如果系統Parses > Executions,就可能出現該比率小於0的情況。本例中,對於每個分析來說大約執行了2.1次。該值<0通常說明shared pool設定或效率存在問題,造成反覆解析,reparse可能較嚴重,或者可是同snapshot有關,如果該值為負值或者極低,通常說明資料庫效能存在問題。
Latch Hit %:要確保>99%,否則存在嚴重的效能問題,比如繫結等會影響該引數。
Parse CPU to Parse Elapsd %:計算公式為:Parse CPU to Parse Elapsd %= 100*(parse time cpu / parse time elapsed)。即:解析實際執行時間/(解析實際執行時間+解析中等待資源時間)。此處為11.4%,非常低,用於解析花費的每個CPU秒花費了大約8.77秒的wall clock時間,這說明花了很多時間等待一個資源。如果該比率為100%,意味著CPU時間等於經過的時間,沒有任何等待。
% Non-Parse CPU:計算公式為:% Non-Parse CPU =round(100*1-PARSE_CPU/TOT_CPU),2)。太低表示解析消耗時間過多。與PARSE_CPU相比,如果TOT_CPU很高,這個比值將接近100%,這是很好的,說明計算機執行的大部分工作是執行查詢的工作,而不是分析查詢的工作。
4.Shared Pool相關統計資料
Shared Pool Statistics Begin End
------ ------
Memory Usage %: 60.45 62.42
% SQL with executions>1: 81.38 78.64
% Memory for SQL w/exec>1: 70.36 68.02 

Memory Usage %:正在使用的共享池的百分率。這個數字應該長時間穩定在75%~90%。如果這個百分率太低,就浪費記憶體。如果這個百分率太高,會使共享池外部的元件老化,如果SQL語句被再次執行,這將使得SQL語句被硬解析。在一個大小合適的系統中,共享池的使用率將處於75%到略低於90%的範圍內。
% SQL with executions>1:這是在共享池中有多少個執行次數大於一次的SQL語句的度量。在一個趨向於迴圈執行的系統中,必須認真考慮這個數字。在這個迴圈系統中,在一天中相對於另一部分時間的部分時間裡執行了一組不同的SQL語句。在共享池中,在觀察期間將有一組未被執行過的SQL語句,這僅僅是因為要執行它們的語句在觀察期間沒有執行。只有系統連續執行相同的SQL語句組,這個數字才會接近100%。這裡顯示,在這個共享池中幾乎有80%的SQL語句在18分鐘的觀察視窗中執行次數多於一次。剩下的20%的語句可能已經在那裡了--系統只是沒有理由去執行它。
% Memory for SQL w/exec>1:這是與不頻繁使用的SQL語句相比,頻繁使用的SQL語句消耗記憶體多少的一個度量。這個數字將在總體上與% SQL with executions>1非常接近,除非有某些查詢任務消耗的記憶體沒有規律。
在穩定狀態下,總體上會看見隨著時間的推移大約有75%~85%的共享池被使用。如果Statspack報表的時間視窗足夠大到覆蓋所有的週期,執行次數大於一次的SQL語句的百分率應該接近於100%。這是一個受觀察之間持續時間影響的統計數字。可以期望它隨觀察之間的時間長度增大而增大。
5.首要等待事件
常見等待事件說明:
oracle等待事件是衡量oracle執行狀況的重要依據及指示,主要有空閒等待事件和非空閒等待事件。
TIMED_STATISTICS:=TRUE,等待事件按等待的時間排序,= FALSE,等待事件按等待的數量排序。
執行statspack期間必須session上設定TIMED_STATISTICS = TRUE。
空閒等待事件是oracle正等待某種工作,在診斷和最佳化資料庫時候,不用過多注意這部分事件,非空閒等待事件專門針對oracle的活動,指資料庫任務或應用程式執行過程中發生的等待,這些等待事件是我們在調整資料庫應該關注的。
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~ % Total
Event Waits Time (s) Ela Time
-------------------------------------------- ------------ ----------- --------
db file sequential read 22,154 259 62.14
CPU time 49 11.67
log file parallel write 2,439 26 6.30
db file parallel write 400 22 5.32
SQL*Net message from dblink 4,575 15 3.71
------------------------------------------------------------- 

這裡是比其他任何事件都能使速度減慢的事件。比較影響效能的常見等待事件:
db file scattered read:該事件通常與全表掃描有關。因為全表掃描是被放入記憶體中進行的進行的,通常情況下它不可能被放入連續的緩衝區中,所以就散佈在緩衝區的快取中。該指數的數量過大說明缺少索引或者限制了索引的使用(也可以調整optimizer_index_cost_adj)。這種情況也可能是正常的,因為執行全表掃描可能比索引掃描效率更高。當系統存在這些等待時,需要透過檢查來確定全表掃描是否必需的來調整。如果經常必須進行全表掃描,而且表比較小,把該表存人keep池。如果是大表經常進行全表掃描,那麼應該是OLAP系統,而不是OLTP的。
db file sequential read:該事件說明在單個資料塊上大量等待,該值過高通常是由於表間連線順序很糟糕,或者使用了非選擇性索引。透過將這種等待與statspack報表中已知其它問題聯絡起來(如效率不高的sql),透過檢查確保索引掃描是必須的,並確保多表連線的連線順序來調整, DB_CACHE_SIZE可以決定該事件出現的頻率。
db file sequential read:該事件說明在單個資料塊上大量等待,該值過高通常是由於表間連線順序很糟糕,或者使用了非選擇性索引。透過將這種等待與statspack報表中已知其它問題聯絡起來(如效率不高的sql),透過檢查確保索引掃描是必須的,並確保多表連線的連線順序來調整,DB_CACHE_SIZE可以決定該事件出現的頻率。
buffer busy wait:當緩衝區以一種非共享方式或者如正在被讀入到緩衝時,就會出現該等待。該值不應該大於1%,確認是不是由於熱點塊造成(如果是可以用反轉索引,或者用更小塊大小)。
latch free:常跟應用沒有很好的應用繫結有關。閂鎖是底層的佇列機制(更加準確的名稱應該是互斥機制),用於保護系統全域性區(SGA)共享記憶體結構閂鎖用於防止對記憶體結構的並行訪問。如果閂鎖不可用,就會記錄一次閂鎖丟失。絕大多數得閂鎖問題都與使用繫結變數失敗(庫快取閂鎖)、生成重作問題(重執行分配閂鎖)、快取的爭用問題(快取LRU鏈) 以及快取的熱資料寬塊(快取鏈)有關。當閂鎖丟失率高於0.5%時,需要調整這個問題。
log buffer space:日誌緩衝區寫的速度快於LGWR寫REDOFILE的速度,可以增大日誌檔案大小,增加日誌緩衝區的大小,或者使用更快的磁碟來寫資料。
logfile switch:通常是因為歸檔速度不夠快,需要增大重做日誌。
log file sync:當一個使用者提交或回滾資料時,LGWR將會話得重做操作從日誌緩衝區填充到日誌檔案中,使用者的程式必須等待這個填充工作完成。在每次提交時都出現,如果這個等待事件影響到資料庫效能,那麼就需要修改應用程式的提交頻率, 為減少這個等待事件,須一次提交更多記錄,或者將重做日誌REDO LOG檔案訪在不同的物理磁碟上。
Wait time: 等待時間包括日誌緩衝的寫入和傳送操作。
6.資料庫使用者程式發生的所有等待事件
Wait Events for DB: BLISSDB Instance: blissdb Snaps: 4 -5
-> s - second
-> cs - centisecond - 100th of a second
-> ms - millisecond - 1000th of a second
-> us - microsecond - 1000000th of a second
-> ordered by wait time desc, waits desc (idle events last)
Avg
Total Wait wait Waits
Event Waits Timeouts Time (s) (ms) /txn
---------------------------- ------------ ---------- ---------- ------ --------
db file sequential read 22,154 0 259 12 886.2
log file parallel write 2,439 2,012 26 11 97.6
db file parallel write 400 0 22 55 16.0
SQL*Net message from dblink 4,575 0 15 3 183.0
SQL*Net more data from dblin 64,490 0 13 0 2,579.6
control file parallel write 416 0 5 13 16.6
db file scattered read 456 0 5 11 18.2
write complete waits 9 0 5 568 0.4
control file sequential read 370 0 5 13 14.8
log buffer space 126 0 4 34 5.0
free buffer waits 11 1 3 313 0.4
log file switch completion 13 0 2 188 0.5
log file sync 90 0 1 8 3.6
log file sequential read 10 0 0 16 0.4
latch free 17 6 0 8 0.7
direct path read 56 0 0 1 2.2
direct path write 56 0 0 1 2.2
SQL*Net more data to client 173 0 0 0 6.9
SQL*Net message to dblink 4,575 0 0 0 183.0
LGWR wait for redo copy 8 0 0 1 0.3
log file single write 10 0 0 1 0.4
db file single write 5 0 0 0 0.2
SQL*Net break/reset to clien 5 0 0 0 0.2
async disk IO 15 0 0 0 0.6
SQL*Net message from client 789 0 3,290 4170 31.6
virtual circuit status 36 36 1,082 30069 1.4
wakeup time manager 34 34 1,034 30403 1.4
SQL*Net message to client 791 0 0 0 31.6
SQL*Net more data from clien 30 0 0 0 1.2
------------------------------------------------------------- 

7.資料庫後臺程式發生的等待事件
Background Wait Events for DB: BLISSDB Instance: blissdb Snaps: 4 -5
-> ordered by wait time desc, waits desc (idle events last)
Avg
Total Wait wait Waits
Event Waits Timeouts Time (s) (ms) /txn
---------------------------- ------------ ---------- ---------- ------ --------
log file parallel write 2,439 2,012 26 11 97.6
db file parallel write 400 0 22 55 16.0
control file parallel write 406 0 5 13 16.2
control file sequential read 258 0 4 16 10.3
db file sequential read 19 0 1 51 0.8
log buffer space 24 0 0 9 1.0
log file sequential read 10 0 0 16 0.4
latch free 14 6 0 9 0.6
db file scattered read 6 0 0 14 0.2
direct path read 56 0 0 1 2.2
direct path write 56 0 0 1 2.2
LGWR wait for redo copy 8 0 0 1 0.3
log file single write 10 0 0 1 0.4
rdbms ipc message 7,339 3,337 3,172 432 293.6
pmon timer 373 373 1,083 2903 14.9
smon timer 3 3 924 ###### 0.1
------------------------------------------------------------- 

8.TOP SQL
調整首要的25個緩衝區讀操作和首要的25個磁碟讀操作做的查詢,將可對系統效能產生5%到5000%的增益。
SQL ordered by Gets for DB: BLISSDB Instance: blissdb Snaps: 4 -5
-> End Buffer Gets Threshold: 10000
-> Note that resources reported for PL/SQL includes the resources used by
all SQL statements called within the PL/SQL code. As individual SQL
statements are also reported, it is possible and valid for the summed
total % to exceed 100
CPU Elapsd
Buffer Gets Executions Gets per Exec %Total Time (s) Time (s) Hash Value
--------------- ------------ -------------- ------ -------- --------- ----------
1,230,745 1 1,230,745.0 27.5 16.39 60.69 1574310682
Module: PL/SQL Developer
insert into city_day_cal select * from rptuser.city_day_cal@db15
1
143,702 1 143,702.0 3.2 1.75 18.66 3978122706
Module: PL/SQL Developer
insert into city_day_cal select * from rptuser.city_day_cal@db15
1 where curtime between to_date('200501','yyyymm') and to_date('
200502','yyyymm')-1 

在報表的這一部分,透過Buffer Gets對SQL語句進行排序,即透過它執行了多少個邏輯I/O來排序。頂端的註釋表明一個PL/SQL單元的快取獲得(Buffer Gets)包括被這個程式碼塊執行的所有SQL語句的Buffer Gets。因此將經常在這個列表的頂端看到PL/SQL過程,因為儲存過程執行的單獨的語句的數目被總計出來。
SQL ordered by Reads for DB: BLISSDB Instance: blissdb Snaps: 4 -5
-> End Disk Reads Threshold: 1000
CPU Elapsd
Physical Reads Executions Reads per Exec %Total Time (s) Time (s) Hash Value
--------------- ------------ -------------- ------ -------- --------- ----------
3,587 1 3,587.0 13.9 0.17 5.13 3342983569
Module: PL/SQL Developer
select min(curtime),max(curtime) from city_day_cal
1,575 1 1,575.0 6.1 1.75 18.66 3978122706
Module: PL/SQL Developer
insert into city_day_cal select * from rptuser.city_day_cal@db15
1 where curtime between to_date('200501','yyyymm') and to_date('
200502','yyyymm')-1 

這部分透過物理讀對SQL語句進行排序。這顯示引起大部分對這個系統進行讀取活動的SQL,即物理I/O。
SQL ordered by Executions for DB: BLISSDB Instance: blissdb Snaps: 4 -5
-> End Executions Threshold: 100
CPU per Elap per
Executions Rows Processed Rows per Exec Exec (s) Exec (s) Hash Value
------------ --------------- ---------------- ----------- ---------- ----------
748 748 1.0 0.00 0.00 3371479671
select t.name, (select owner_instance from sys.aq$_queue_table_
affinities where table_objno = t.objno) from system.aq$_queue
_tables t where t.name = :1 and t.schema = :2 for update skip lo
cked
442 1,142 2.6 0.00 0.00 1749333492
select position#,sequence#,level#,argument,type#,charsetid,chars
etform,properties,nvl(length, 0), nvl(precision#, 0),nvl(scale,
0),nvl(radix, 0), type_owner,type_name,type_subname,type_linknam
e,pls_type from argument$ where obj#=:1 and procedure#=:2 order
by sequence# desc 

這部分告訴我們在這段時間中執行最多的SQL語句。為了隔離某些頻繁執行的查詢,以觀察是否有某些更改邏輯的方法以避免必須如此頻繁的執行這些查詢,這可能是很有用的。或許一個查詢正在一個迴圈的內部執行,而且它可能在迴圈的外部執行一次,可以設計簡單的演算法更改以減少必須執行這個查詢的次數。即使它執行的飛快,任何被執行幾百萬次的操作都將開始耗盡大量的時間。
9.例項活動
Instance Activity Stats for DB: BLISSDB Instance: blissdb Snaps: 4 -5
Statistic Total per Second per Trans
--------------------------------- ------------------ -------------- ------------
CPU used by this session 4,870 4.5 194.8
CPU used when call started 4,870 4.5 194.8
CR blocks created 45 0.0 1.8
DBWR buffers scanned 24,589 22.8 983.6
DBWR checkpoint buffers written 14,013 13.0 560.5
DBWR checkpoints 5 0.0 0.2
……
dirty buffers inspected 38,834 36.0 1,553.4 --髒緩衝的個數
free buffer inspected 40,463 37.5 1,618.5 --如果數量很大,說明緩衝區過小
…… 

10.I/O
下面兩個報表是面向I/O的。通常,在這裡期望在各裝置上的讀取和寫入操作是均勻分佈的。要找出什麼檔案可能非常“熱”。一旦DBA瞭解瞭如何讀取和寫入這些資料,他們也許能夠透過磁碟間更均勻的分配I/O而得到某些效能提升。
Tablespace IO Stats for DB: BLISSDB Instance: blissdb Snaps: 4 -5
->ordered by IOs (Reads + Writes) desc
Tablespace
------------------------------
Av Av Av Av Buffer Av Buf
Reads Reads/s Rd(ms) Blks/Rd Writes Writes/s Waits Wt(ms)
-------------- ------- ------ ------- ------------ -------- ---------- ------
BLISS_DATA
17,649 16 12.3 1.2 44,134 41 0 0.0
UNDOTBS1
4,484 4 9.6 1.0 29,228 27 0 0.0
SYSTEM
340 0 31.0 1.1 36 0 0 0.0 

File IO Stats for DB: BLISSDB Instance: blissdb Snaps: 4 -5
->ordered by Tablespace, File
Tablespace Filename
------------------------ ----------------------------------------------------
Av Av Av Av Buffer Av Buf
Reads Reads/s Rd(ms) Blks/Rd Writes Writes/s Waits Wt(ms)
-------------- ------- ------ ------- ------------ -------- ---------- ------
BLISS_DATA D:ORACLEORADATABLISSDBBLISS01.DBF
5,779 5 12.0 1.2 14,454 13 0
D:ORACLEORADATABLISSDBBLISS02.DBF
5,889 5 12.1 1.2 14,772 14 0
D:ORACLEORADATABLISSDBBLISS03.DBF
5,981 6 12.6 1.2 14,908 14 0 

11.緩衝池
Buffer Pool Statistics for DB: BLISSDB Instance: blissdb Snaps: 4 -5
-> Standard block size Pools D: default, K: keep, R: recycle
-> Default Pools for other block sizes: 2k, 4k, 8k, 16k, 32k
Free Write Buffer
Number of Cache Buffer Physical Physical Buffer Complete Busy
P Buffers Hit % Gets Reads Writes Waits Waits Waits
--- ---------- ----- ----------- ----------- ---------- ------- -------- ------
D 3,000 99.4 4,482,816 25,756 73,470 11 9 0
------------------------------------------------------------- 

如果我們使用多緩衝池的功能,上面的報表會告訴我們緩衝池引起的使用故障。實際上這只是我們在報表的開頭看到的資訊的重複。
12.回滾段活動
Instance Recovery Stats for DB: BLISSDB Instance: blissdb Snaps: 4 -5
-> B: Begin snapshot, E: End snapshot
Targt Estd Log File Log Ckpt Log Ckpt
MTTR MTTR Recovery Actual Target Size Timeout Interval
(s) (s) Estd IOs Redo Blks Redo Blks Redo Blks Redo Blks Redo Blks
- ----- ----- ---------- ---------- ---------- ---------- ---------- ----------
B 37 17 169 4012 3453 184320 3453
E 37 32 1385 57132 184320 184320 436361
------------------------------------------------------------- 
一般期望活動在各回滾段間(除了SYSTEM回滾段外)均勻分佈。在檢查報表的這一部分時,報表標題也具有需要記住的最有用資訊。尤其是,如果完全使用最佳設定時關於Optmal比Avg Active更大的建議。因為這是與DBA最有關的活動(I/O和回滾段資訊)。

資料庫的等待事件,發現前幾名是:
log file parallel write 

db file scattered read 

log file sync 

db file sequential read 

SQL*Net more data to client

發現前面的4項都是影響到資料庫效能的問題:

log file sync:

這個等待時間是指等待oracle的前臺的commit和rollback操作程式完成,有時候這個等待時間也會包括等待LGWR程式把一個會話事務的日誌記錄資訊從日誌緩衝區中寫到磁碟上的重做日誌檔案中。因此當前臺程式在等待這個事件的時候,LGWR程式同時也在等待事件log file parallel write。

理解什麼造成這個等待事件的關鍵在於:對比這個等待事件和log file parallel write等待事件的平均等待時間:

l 如果他們的等待時間差不多,那麼就是重做日誌檔案的I/O引起了這個等待事件,則需要調整重做日誌檔案的I/O,

l 如果log file parallel write等待事件的平均等待時間明顯小於log file sync等待事件的等待時間,那麼就是一些其他寫日誌的機制在commit和rollback操作時引起的等待,而不是I/O引起的等待。例如重做日誌檔案的latch競爭,會伴隨出現latch free或者LGWR wait for redo copy等待事件

在V$SESSION_WAIT中,這個等待事件有3個引數:

P1
 代表在日誌緩衝區中需要被寫入到重做日誌檔案中的快取數量,寫入的同時會確認事務是否已經被提交,並且保留提交資訊到例項意外中斷前,因此必須等待LGWR將P1數量的快取寫入重做日誌檔案為止。
 
P2
 無用
 
P3
 無用
 

如果這個等待事件在整個等待事件中佔了比較大的比重,可以從3個方面來進行調整

1. 調整LGWR程式時期具有更好的磁碟I/O吞吐量,例如不要將日誌檔案放在RAID5的磁碟上

2. 如果存在很多執行時間很短的事務,可以考慮將這些事務合併成一個批次事務以減少提交的次數,因為每次提交都需要確認相關的日誌寫入重做日誌檔案,因此使用批次事務來減少提交的次數是一種非常行之有效的減少I/O的方法

3. 產看是否有一些操作可以安全的使用NOLOGGING或者UNRECOVERABLE選項,這樣可以減少日誌檔案的產生

Log file parallel write

這個等待事件出現在黨LGWR後臺程式從日誌緩衝區寫日誌資訊到磁碟上的重做日誌檔案的時候。只有啟用了非同步I/O的時候,LGWR程式才會並行寫當前日誌組內的充作日誌檔案,否則LGWR指揮迴圈順序逐個的寫當前日誌組重做日誌檔案。LGWR程式不得不等待當前日誌組所有的重做日誌檔案成員全部寫完,因此,決定這個等待事件的等待時間長短的主要因素是重做日誌檔案所在磁碟的I/O讀寫速度。

如果是當前LGWR程式寫的速度不夠快導致這個等待事件,可以透過檢視一些和重做日誌相關的統計值來判定當前的LGWR程式是否效率低下,具體的可以看 redo writes, redo blocks written, redo write time, rdo wastage, redo size等統計值,這些都是和LGWR程式效能直接相關的一些統計值。

在V$SESSION_WAIT中,這個等待事件的3個引數:

P1
 代表正在被寫入的重做日誌檔案組中的重做日誌檔案號
 
P2
 代表需要寫入重做日誌組中每個重做日誌檔案的重做日誌block數量
 
P3
 代表I/O請求次數,需要被寫入的block會被分成多次分別請求
 

如果這個等待事件佔用比較多的時間,可以做如下調整

1. 採用UNRECOVERABLE/NOLOGGING操作儘量減少重做日誌的產生

2. 在保證不會同時對市重做日誌檔案的前提下,儘量減少重做日誌組中的成員個數,減少每次寫重做日誌檔案的時間

3. 除非在備份情況下,否則不要在江表空間置於熱備份的模式下,因為在表空間處於熱備的模式下會產生更多的重做日誌檔案

4. 對於使用LogMiner、Logical Standby或者Streams,在能夠滿足要求功能的前提下,儘量使用最低階別的追加日誌以減少重做日誌的產生

5. 儘量將同一個日誌組內的重做日誌檔案分散到不同的硬碟上,減少並行寫重做日誌檔案時產生的I/O競爭

6. 不要將重做日誌檔案置於RAID5的磁碟上,最好放在裸裝置上。

7. 如果設定了歸檔模式,不要將歸檔日誌的目的地設定為存放重做日誌的磁碟上,避免引起I/O競爭

關於Log的這2個問題的總結

透過上述對Log這2個問題的描述,以及產生的原因,除了Log file sync可能有其他方面的因素引起的(Latch),主要還是磁碟和使用習慣

1. 磁碟由於這些都是寫磁碟所引起的,所以只有從減少寫磁碟(指資料庫本身的角度,和下列提到的使用者操作習慣不一樣)和加快寫磁碟來減少這些等待時間

a) 儘量不要在RAID5的磁碟上儲存重做日誌檔案,RAID5寫的速度屬於比較慢的

b) 在安全性保證的基礎上,減少重做日誌組成員的個數

c) 同一個日誌組中的不同成員放在不同的磁碟上,加速寫的速度。

d) 對可以採用NOLOGGING/UNRECOVERABLE的操作,使用這些選項減少log的產生

e) 有歸檔的,不要將歸檔的和線上重做日誌放在一個磁碟上

2. 使用習慣如果使用者不斷的進行commit或者rollback,這樣必定引起一次log日誌的寫操作。因此可以透過一些統計資訊判斷是否每次的日誌的寫運算元據量很小,這樣透過調節使用者的操作,將大量的資料更新合併到一個事務中來,這樣增加每次日誌的操作量,減少對日誌的不斷呼叫,提高LGWR的寫的效率。

db file scattered read 

這是一個非常常見的等待時間。當oracle從磁碟上讀取多個block到不連續的快取記憶體區的快取中就會發生這個等待事件,Oracle一次最多能夠讀入的block數量由初始化引數DB_FILE_MULTIBLOCK_READ_COUND決定,這個時間一般伴隨著全表掃描或者Fast Full Index 掃描一起出現。

在V$SESSION_WAIT中,這個等待事件的幾個引數:

P1
 代表oracle的檔案號
 
P2
 代表從這個檔案中開始讀取的block號
 
P3
 代表從這個block開始需要讀取的block數量
 

一般從這個3個引數,就可以回頭查詢到是在讀取資料庫的哪個物件,然後分析對這個物件的操作來進行最佳化Sql語句。

如果這個等待事件佔的比重比較厲害,可以透過以下方法來調整

方法一

找出執行全表掃描或者Fast Full index掃描的Sql語句,判斷這些掃描是否是必要的,是否導致了比較差的執行計劃,進行調整。

從oracle9i開始,提供了一個檢視V$SQL_PLAN,可以透過它幫助我們找到那些全表掃描或者Fast Full Index掃描的Sql語句:

查詢全表掃描的SQL語句

Select sql_text from v$sqltext t, v$sql_plan p

Where t.hash_value=p.hash_value

And p.operation=’TABLE ACCESS’

And p.option=’FULL’

Order by p.hash-value, t.piece;
 

查詢Fast Full index 掃描的Sql語句可以這樣;

Select sql_text from v$sqltext t, v$sql_plan p

Where t.hash_value=p.hash_value

And p.operation=’INDEX’

And p.option=’FULL SCAN’

Order by p.hash-value, t.piece;
 

如果是Oracle8i的資料庫,可以透過v$session_event檢視中找到關於這個等待事件的程式sid,然後根據這個sid來跟蹤相應會話的SQL

Select sid, event from v$session_event 

Where event=’db file sequential read’
 

或者可以透過檢視物理讀取最多的SQL語句的執行計劃,看是否裡面包含了全表掃描和Fast Full Index掃描,可以透過以下語句獲取物理讀取最多的SQL語句

Select sql_text from

Select *from v$sqlarea

Order by disk_reads)

Where rownum<10
 

方法二:

有時候執行計劃很好也會出現多block掃描的情況,這個時候可以透過調整Oracle資料庫的多block的I/O,來設定一個合理的DB_FILE_MULTIBLOCK_READ_COUNT,使得儘量滿足;

Db_block_size * DB_FILE_MULTIBLOCK_READ_COUNT = max io size of system

這個引數也不是設定的越大越好,設定這個引數之前需要了解一下應用的型別,如果是OLTP型別的,一般來說全表掃描較少,這個時候如果設定了比較大反而會降低資料庫的效能,因為CBO在某些情況下會因為多block讀取導致COST比較低從而錯誤的選用了全表掃描。

其他方法

還可以採用對錶和索引使用分割槽、將快取區的LRU末端的全表掃描和FastFullIndex掃描的block放入到Keep快取池等方法來進行調節。

db file sequential read

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

相關文章