oracle性能優化之awr分析html
做者:bingjavajava
最近某證券公司系統在業務期間系統運行緩慢,初步排查懷疑是數據庫存在性能問題,所以導出了oracle的awr報告進行分析,在此進行記錄。sql
致使系統的性能問題有不少,好比內存、cpu佔用率太高,網絡延遲、系統存儲io瓶頸、還有程序方面的代碼邏輯、性能低下的sql語句等等,這裏主要從awr的角度說明如何經過awr的報告來定位問題。數據庫
1、awr報告分析及問題定位
DB Name 性能優化 |
DB Id 服務器 |
Instance 網絡 |
Inst num session |
Release 數據結構 |
RAC 併發 |
Host |
**DB |
1527139216 |
**DB |
1 |
10.2.0.5.0 |
NO |
p3-**DB |
Snap Id |
Snap Time |
Sessions |
Cursors/Session |
|
Begin Snap: |
16021 |
01-Mar-16 10:00:34 |
213 |
2.4 |
End Snap: |
16022 |
01-Mar-16 11:00:36 |
213 |
2.3 |
Elapsed: |
|
60.04 (mins) |
|
|
DB Time: |
|
176.32 (mins) |
|
|
關鍵項說明:
DB TIME:表明了此統計期間的數據庫負載,是全部前臺session花費在database調用上的總和時間(包括CPU時間、IO Time、和其餘一系列非空閒等待時間)。若是 DB Time 接近於 Elapsed Time*cpu 數,代表數據庫比較忙,cpu 負載也許比較大。這時頗有多是由於資源爭用致使等待事件的結果,能夠去 top 5 等待事件分析緣由。
Operating System Statistics
Statistic |
Total |
|
BUSY_TIME |
1,037,128 |
|
IDLE_TIME |
10,487,927 |
|
IOWAIT_TIME |
19,061 |
|
NICE_TIME |
316 |
|
SYS_TIME |
132,552 |
|
USER_TIME |
882,792 |
|
LOAD |
3 |
|
RSRC_MGR_CPU_WAIT_TIME |
0 |
|
VM_IN_BYTES |
1,274,466,304 |
|
VM_OUT_BYTES |
2,174,697,472 |
|
PHYSICAL_MEMORY_BYTES |
33,712,308,224 |
|
NUM_CPUS |
32 |
|
NUM_CPU_SOCKETS |
2 |
從以上信息可知:
單數據庫實例,非集羣部署模式;2個物理cpu(NUM_CPU_SOCKETS=2),32個邏輯cpu(NUM_CPUS=32)。
cpu利用率爲:DB Time /(Elapsed* NUM_CPUS)=176/(60*32) *100%=9.2%
cpu的負載處於正常水平。
Load Profile
Per Second |
Per Transaction |
|
Redo size: |
89,367.47 |
21,227.40 |
Logical reads: |
105,600.68 |
25,083.26 |
Block changes: |
458.93 |
109.01 |
Physical reads: |
27,716.84 |
6,583.56 |
Physical writes: |
30.80 |
7.32 |
User calls: |
3,675.70 |
873.09 |
Parses: |
324.60 |
77.10 |
Hard parses: |
14.13 |
3.36 |
Sorts: |
44.47 |
10.56 |
Logons: |
1.69 |
0.40 |
Executes: |
340.07 |
80.78 |
Transactions: |
4.21 |
|
% Blocks changed per Read: |
0.43 |
Recursive Call %: |
16.91 |
Rollback per transaction %: |
0.09 |
Rows per Sort: |
397.30 |
Redosize:每秒產生的日誌大小(單位字節),可標誌數據變動頻率,大的redosize每每對lgwr寫日誌,和arch歸檔形成I/O壓力,也有可能形成logbuffer堵塞從而產生相關的等待事件。很繁忙的系統中日誌生成量可能達到幾百k,甚至幾M。在Top 5 Timed Events中未發現log方面的等待事件,說明redo生成的頻率屬於正常範圍。
Logical reads: 從內存中讀取數據的次數(次數*塊數),每秒鐘邏輯讀數據量:105,600.68*8k=825m
Physical reads:當從內存中未都到數據時則從硬盤上讀取數據,每秒物理讀數據量:27,716.84 *8k=216m
Physical reads / Logical reads=27,716.84/105,600.68=26%,有26%的邏輯讀致使了物理io。所以此處的物理io多是系統的性能瓶頸(具體需在後面的 top 5中進行分析)。
Instance Efficiency Percentages (Target 100%)
Buffer Nowait %: |
98.73 |
Redo NoWait %: |
100.00 |
Buffer Hit %: |
73.77 |
In-memory Sort %: |
100.00 |
Library Hit %: |
89.85 |
Soft Parse %: |
95.65 |
Execute to Parse %: |
4.55 |
Latch Hit %: |
96.92 |
Parse CPU to Parse Elapsd %: |
95.60 |
% Non-Parse CPU: |
96.41 |
buffer hit:表示進程從內存中找到數據塊的比率,監視這個值是否發生重大變化比這個 值自己更重要。對於通常的 OLTP 系統,一般應在 95%以上。不然應考慮加大 db_cache_size, 可是大量的非選擇的索引也會形成該值很高(大量的 db file sequential read)。
Latch Hit:Latch是一種保護內存結構的鎖,能夠認爲是SERVER進程獲取訪問內存數據結構的許可。要確保Latch Hit>99%,不然意味着Shared Pool latch爭用,可能因爲未共享的SQL,或者Library Cache過小,可以使用綁定變動或調大Shared Pool解決。
Execute to Parse:是語句執行與分析的比例,若是要SQL重用率高,則這個比例會很高。該值越高表示一次解析後被重複執行的次數越多。
Parse CPU to Parse Elapsd:該指標反映了快照內解析CPU時間和總的解析時間的比值(Parse CPU Time/ Parse Elapsed Time); 若該指標水平很低,那麼說明在整個解析過程當中 實際在CPU上運算的時間很短,而主要的解析時間都耗費在各類其餘非空閒的等待事件上了,此值越高越好。
Shared Pool Statistics
Begin |
End |
|
Memory Usage %: |
56.42 |
55.58 |
% SQL with executions>1: |
54.12 |
49.23 |
% Memory for SQL w/exec>1: |
49.88 |
48.29 |
SQL with executions
:表明了sql重複執行的比例,本報告中是54%,是比較低的,說明存在sql硬編碼的狀況,同時上面的Execute to Parse也只有4.55%,也說明了sql解析的重用率低。
內存利用率爲55%左右,屬於正常狀況。
Top 5 Timed Events
業務11:00-12:00期間:
Event |
Waits |
Time(s) |
Avg Wait(ms) |
% Total Call Time |
Wait Class |
CPU time |
|
10,028 |
|
94.8 |
|
db file scattered read |
6,943,920 |
644 |
0 |
6.1 |
User I/O |
read by other session |
4,837,558 |
578 |
0 |
5.5 |
User I/O |
CSS initialization |
13 |
65 |
4,967 |
.6 |
Other |
db file sequential read |
512,027 |
58 |
0 |
.6 |
User I/O |
業務15:00-16:00期間
Event |
Waits |
Time(s) |
Avg Wait(ms) |
% Total Call Time |
Wait Class |
||
CPU time |
|
2,569 |
|
95.8 |
|
||
SQL*Net more data to client |
1,150,806 |
233 |
0 |
8.7 |
Network |
||
db file scattered read |
1,381,500 |
136 |
0 |
5.1 |
User I/O |
||
CSS initialization |
13 |
63 |
4,878 |
2.4 |
Other |
||
db file sequential read |
42,488 |
30 |
1 |
1.1 |
User I/O |
db file scattered read:
代表Oracle內核請求從磁盤讀取多個數據塊到buffer cache中,
這種狀況一般顯示與全表掃描相關的等待。當數據庫進行全表掃時,基於性能的考慮, 數據會分散讀入Buffer Cache。若是這個等待事件比較顯著,可能說明對於某些全表掃描的表,沒有建立索引或者沒有建立合適的索引。
read by other session:
Oracle 操做的最小單位是塊(Block),當對數據塊作修改時,其餘的會話將被阻止對這個數據塊上的數據作修改,可是能夠以一致性的方式讀取這個數據塊(from undo)。當前的用戶修改完這個數據塊後,將會當即釋放掉加在這個數據塊上的排他鎖,這樣另外一個會話就能夠繼續修改它,這種加鎖的機制叫Latch。當一個會話將數據塊都到內存中時,其它的會話同時也請求了這個數據塊,就致使被等待的會話出現read by other session。而當前會話通常是db file scattered read或db file sequential read。
從本次awr報告中都發現,db file scattered read、db file sequential read、read by other session這幾個事件的等待次數很高,所以能夠判斷當前業務場景存在熱點塊競爭問題。
SQL*Net more data to client:
當服務器端有太多的數據須要發給客戶端時,可能會產生此等待事件,也可能因爲網絡問題致使服務器沒法及時地將信息或者處理結果發送給客戶端, 一樣會產生這個等待。在15:00--16:00業務期間此等待事件相對較高,從SQL*Net看並不像應用程序(應用程序是JDBC Thin Client),多是第三方的oracle監控程序致使的。
File IO Stats
Tablespace |
Filename |
Reads |
Av Reads/s |
Av Rd(ms) |
Av Blks/Rd |
Writes |
Av Writes/s |
Buffer Waits |
Av Buf Wt(ms) |
||||
JSZ35_TBS |
*tbs01.dbf |
2,635,786 |
732 |
0.10 |
14.88 |
4,032 |
1 |
2,016,907 |
0.12 |
||||
JSZ35_TBS |
*tbs02.dbf |
2,730,384 |
758 |
0.09 |
12.89 |
10,420 |
3 |
1,679,836 |
0.12 |
||||
JSZ35_TBS |
*tbs03.dbf |
2,084,937 |
579 |
0.08 |
12.19 |
9,183 |
3 |
1,141,265 |
0.13 |
以上數據文件,平均每秒被讀700屢次,平均每秒讀取的數據塊爲14塊左右。
Tablespace IO Stats
Tablespace |
Reads |
Av Reads/s |
Av Rd(ms) |
Av Blks/Rd |
Writes |
Av Writes/s |
Buffer Waits |
Av Buf Wt(ms) |
||||
JSZ35_TBS |
1,420,317 |
394 |
0.11 |
14.73 |
9,502 |
3 |
113 |
2.30 |
Segments by Buffer Busy Waits
Owner |
Tablespace Name |
Object Name |
Subobject Name |
Obj. Type |
Buffer Busy Waits |
% of Capture |
|||
JSZ35 |
JSZ35_TBS |
TF_SUBJECTPRICE_TMP |
|
TABLE |
30 |
32.26 |
|||
JSZ35 |
JSZ35_TBS |
IND_T_*LOG |
|
INDEX |
21 |
22.58 |
|||
JSZ35 |
JSZ35_TBS |
PK_T_**_TMP |
|
INDEX |
15 |
16.13 |
|||
JSZ35 |
JSZ35_TBS |
T_***HER |
CHER_P2016 |
TABLE PARTITION |
9 |
9.68 |
|||
JSZ35 |
JSZ35_TBS |
IND_T_***HER |
|
INDEX |
7 |
其它業務時間段:
Owner |
Tablespace Name |
Object Name |
Subobject Name |
Obj. Type |
Buffer Busy Waits |
% of Capture |
|||
JSZ35 |
JSZ35_TBS |
IND_T_*LOG |
|
INDEX |
60 |
68.18 |
|||
JSZ35 |
JSZ35_TBS |
IND_T_***SED |
|
INDEX |
20 |
22.73 |
JSZ35 |
JSZ35_TBS |
TF_SUBJECTPRICE_TMP |
TABLE |
18 |
17.65 |
|||
JSZ35 |
JSZ35_TBS |
IND_T_***HER |
INDEX |
7 |
6.86 |
Segments by Physical Reads
Owner |
Tablespace Name |
Object Name |
Subobject Name |
Obj. Type |
Physical Reads |
%Total |
|||
JSZ35 |
JSZ35_TBS |
T_***NCE |
ANCE_P2015 |
TABLE PARTITION |
81,573,441 |
81.70 |
|||
JSZ35 |
JSZ35_TBS |
T_***NCE |
ANCE_P2016 |
TABLE PARTITION |
12,884,029 |
12.90 |
|||
JSZ35 |
JSZ35_TBS |
T_***CE |
RICE_P2016 |
TABLE PARTITION |
3,471,341 |
3.48 |
熱點數據塊主要是T_***NCE、T_***CE引發。
數據塊熱點問題io等待的主要對象爲:
T_***LOG、TF_SUBJECTPRICE_TMP、TS_PROCESSED、TF_SUBJECTPRICE_TMP、T_***NCE、T_***CE
可結合SQL ordered by CPU Time(最耗時的sql)、SQL ordered by Gets(邏輯讀最多的sql)、SQL ordered by Reads(物理讀最多的sql)來定位具體的sql語句。
2、問題總結及解決方式
本報告期,系統的cpu、內存表現正常,形成系統性能問題的主要緣由爲物理讀過多,產生io等待;同時因爲相關業務表存在頻繁的併發訪問現象(邏輯讀較多)且性能較差而致使了數據塊競爭問題。邏輯讀是消耗cpu的,而物理讀是消耗io的,這也說明了系統的大部分時間都消耗在io等待上,因此cpu相對空閒。
優化方案主要包括應用層的優化和oracle數據庫的優化:
1、應用層的優化目標主要在於下降對數據庫的訪問頻率、合理有效使用索引(合理有效使用索引,需經過對sql語句的執行計劃進行分析和調優):
-
T_***LOG可能存在較頻繁的插入數據操做,可採用如下方式減小對數據庫的提交操做:
將此表的單條insert的操做改成批量入庫提交的方式(比例100條記錄入庫一次)。
- T_***_TMP可能存在讀寫混合的場景,需根據業務分析是否有優化的空間。
-
T_***NCE、T_***CE、T_A***T,關於此表的相關訪問應該是最須要優化的了,需優化的sql語句爲(好比索引是否合理):
關鍵的sql語句:其中上面的第一條語句執行狀況,SQL ordered by Elapsed Time:
Elapsed Time (s) |
CPU Time (s) |
Executions |
Elap per Exec (s) |
% Total DB Time |
SQL Id |
SQL Module |
SQL Text |
||
3,519 |
3,601 |
0 |
|
33.26 |
oracle@p3tgbmsdb1 (TNS V1-V3) |
SELECT /*+ LEADING… |
|||
1,305 |
1,086 |
158 |
8.26 |
12.34 |
JDBC Thin Client |
select sum(… |
該語句執行了3600秒(即整個快照期)都還未執行完成,該語句是三張表的關聯統計查詢,oracle自動對其進行並行查詢,可能因爲此三張表(T_A***T、T_***NCE、T_AS**T)的數據量較大,尤爲是T_A***T的數據量較大時更是影響性能,採用並行查詢後反而致使了對io的爭用,下降了性能。
四、全表掃描問題
大表在一小時內發生了822次全表掃描,若是表的數據比較大則對性能有很大影響。小表每秒中有28次全表掃描,需重點優化以上3條sql語句。
table scans (direct read) |
0 |
0.00 |
0.00 |
||
table scans (long tables) |
822 |
0.23 |
0.07 |
||
table scans (rowid ranges) |
0 |
0.00 |
0.00 |
||
table scans (short tables) |
102,749 |
28.52 |
8.27 |
||
total number of times SMON posted |
22 |
0.01 |
2、oracle優化
一、合理設置DB_FILE_MULTIBLOCK_READ_COUNT,此參數控制在多數據塊讀時一次讀入數據塊的次數。適當增長這個參數大小,可以提升多數據塊操做(如全表掃描)的IO效率。
二、能夠考慮對以上熱點表重建索引、分區表等方式來下降該數據段上的IO負荷,將歷史數據進行分離(好比根據業務狀況將2015年以前的數據轉移到另外的備份庫中)。
三、因Buffer Hit只有73%,可根據Buffer Pool Advisory調整buffer pool大小爲:16g。
四、將頻繁併發訪問的表或數據移到另外一數據塊或者進行更大範圍的分佈(能夠增大pctfree值 ,擴大數據分佈,減小競爭)。
五、屬於index block的表(如T_***SED、T_***_TMP),應該考慮重建索引、分割索引或使用反向鍵索引。關於反向鍵索引需根據sql語句查詢特色進行有選擇使用(若是在where中對索引列進行了範圍搜索,則會致使該索引無效會進行全表掃描,反向鍵索引只對<>\=有效)。