性能測試關注的Oracle指標
資料庫的性能優化是個非常複雜的事情,熟悉Oracle的專家能手更是數不勝數,讓哥仰視。所以寫了50篇的帖子都沒敢寫過Oracle。直到最近,單位請來了Oracle原廠培訓(叫Oracle大學),請Oracle大師來給新入職的同學做培訓,哥呢,作為一個張羅這事的參與者之一,也跟著聽了一天。聽了一天竟然發現大師有幾個地方講錯了,主要是在理論聯繫實際的問題分析、AWR報告解讀方面,提問之後竟然把大師掛在了台上。後來想了想,大師也有不懂的,我怕什麼呢,寫!哥從性能測試的角度看Oracle,換個視角。
一個業務的響應時間受到這個業務所以環節性能的影響,如果被測系統涉及到資料庫,則需要對資料庫指標進行監控。這裡的資料庫指標並不是伺服器本身的CPU、內存、IO等指標(當然,這些指標也是要監控的),而是指從資料庫角度來看的指標,例如Buffer命中率、SQL執行時間等,這一章介紹Oracle資料庫的指標。
資料庫的指標千千萬,一般來說,會重點關注一些指標,這裡就介紹一下作為測試人員需要關注的指標。
關注指標之前,需要做的是關注Oracle系統的告警(例如:表空間滿了)。只有告警消除後,各類指標才是正常狀態下的指標。
查看Oracle性能指標的方法有不少,本文主要以AWR報告為目標做介紹。自動工作量存儲(Automatic Workload Repository AWR)是隨著資料庫一起被安裝的,它不僅能收集統計數據,還能從統計數據中分析出度量數據,後續會詳細介紹AWR,本節主要介紹指標本身的概念。
1 SQL語句執行時間、吞吐量
資料庫的用戶是應用,應用使用資料庫來執行SQL語句。SQL語句的執行時間最能反映滿意用戶需要的能力。當一個應用處理速度比較慢的時候,自然會查看資料庫的SQL執行時間。
一個資料庫有千千萬個指標,其他指標即使異常到令人髮指,只要用戶滿意,往往也沒有人去刻意做調優。
執行時間:
在AWR>Main Report>SQL Statistics目錄下,可以看到如下SQL語句執行時間的分目錄。
如果應用程序比較慢,並且比較懷疑是資料庫的原因,那麼關注一下排在前幾位的SQL語句。作為初次觀察,關注SQL ordered by Elapsed Time,這個指標是按照整個SQL的執行時間來排序的,以下圖為例:
這裡有SQL語句的名稱、執行次數(Executions)和每次的執行時間(Elapsed Time per Exec(s))。如果這個執行時間比預想的要長,那麼需要查看一下這個語句的執行計劃。
吞吐量:
執行次數除以總時間(兩個AWR快照之間的時間)就是這條SQL的吞吐量,吞吐量同樣是比較重要的指標。SQL吞吐量無法根據業務壓力而增長說明單條SQL的執行效率有問題或者系統的並發有問題(應用、中間件、資料庫等環節均可能有並發的問題)
另外,%Total、%CPU、%IO這些指標一定要注意這個分目錄的具體解釋,因為每個分目錄下的解釋不一定一樣,並且,這些指標可能和你大腦中想像的含義也不一樣。
%Total:在「SQL ordered by Elapsed Time」這個分目錄下,含義是:這條SQL的執行時間(Elapsed Time)佔總DB Time(所有SQL語句執行的時間之和)的百分比。而在「SQL ordered by CPU Time」這個分目錄下,含義是:CPU Time佔總DB Time的百分比。
%CPU:這條SQL的CPU Time除以Elapsed Time。表示執行時間裡面有多少是花在CPU上的,沒花在CPU上自然就是花在等待上,等待IO或者等待其他資源。
%IO:這條SQL的User I/O Time除以Elapsed Time
我看了解釋以後發現和我的第一想像是不一樣的。在看指標的時候,千萬不要根據自己的猜測、經驗來看,一定要查閱各個系統、各個產品自身對該指標的定義。
這裡再多說幾句,我們個人會對Oracle的一些指標有誤解,那麼Oracle作為一個產品也會對其他產品有誤解。例如,AWR報告的開頭部分:
這一段是Oracle對自身所處的系統環境信息做一個抓取,系統共18個核,72個邏輯CPU,但這個系統不一定有18個核的能力,還得具體查看環境是不是虛擬化平台,如果是,那麼這18個核是虛擬的核,而真正能得到的CPU能力可能小於18。
2 Top等待
如果覺得資料庫有性能問題,那麼最先查看的就是Top等待事件。
看看哪個事件的Total Wait Time最大,就重點解決哪個事件。DB CPU如果最大一般是正常的,需繼續關注DB CPU之外的事件。
等待事件五花八門,遇到沒見過的可以網上查查,但看懂網上查來的結果也是需要些資料庫的知識了,此處不是一朝一夕的花架子。
舉一個性能測試中常見的例子,測試環境或者是剛剛搭建的生產環境常常是Oracle的默認參數,沒有經過調整,log switch佔到了Top等待事件的前面。
日誌切換(Log switch)為什麼等待時間這麼多呢?首先就要了解日誌、日誌組是幹什麼,日誌為什麼要切換,什麼情況下切不過去。
Redo日誌組假如初始是2個日誌,每個日誌10M大小,分別記為A和B。當A寫滿的時候,就要switch到B去寫日誌,這時候就發生了日誌切換。此時,可能1)如果開啟了日誌歸檔,需要將A寫到歸檔日誌裡面。如果B這時候也寫滿了,就要再次switch回A。如果A還沒有歸檔完成,那麼就需要切換等待。可能2)A裡面的內容還沒有完成提交,B也不能把A的日誌衝掉,此時產生了切換等待。
了解清楚之後,在不改變應用程序的情況下,可以通過增加單個日誌大小(減少切換次數)、增加日誌組個數(減少切換時可能的等待)來解決。比如日誌大小從10M改為1G,日誌從2個改為4個。
3 Instance Efficiency Percentages
這個分類下面大部分是Buffer命中率。命中率在資料庫中是至關重要的,命中率的高低直接影響了資料庫的性能。
介紹幾個經常關注的指標
Buffer Nowait >99
在緩衝區中獲取buffer 的未等待比率, 一旦此數據較低說明資料庫存在大量出現buffer busy waits。
Buffer Hit >95
數據塊在數據緩衝區中的命中率,通常應該在95%以上,否則考慮加大db_cache_size。當然,命中率低也不一定是cache小,也可能SQL寫的爛、執行計劃不當等原因。
Library Hit >95
代表著SQL在共享區的命中率,通常在95%以上。
當你發出一條SQL語句交付Oracle,在執行和獲取結果前,Oracle對此SQL將進行幾個步驟的處理過程,語法檢查、語義檢查、對sql語句進行解析、執行SQL返回結果。其中SQL解析的過程生成解析樹(parse tree)及執行計劃(execution plan)。這個過程是非常消耗CPU資源的,因此Oracle將解析好的SQL語句(或者說是執行計劃)放在library cache中等待復用。
較低的庫緩衝區的命中率意味著SQL語句被過早的推出了緩衝區(又要再次硬解析),加大共享池。
Redo Nowait >99
寫日誌的不等待比率,太低可能是log_buffer偏小,或者log_buffer向磁碟刷日誌的參數 _log_io_size(默認為1/3*log_buffer/log_block_size,設置_log_io_size 為合適的值,比如適當減小),或者存放日誌的磁碟性能不好(比如RAID劃分不當,RAID5或6改為RAID10),或者日誌組個數偏少、每個redo log大小偏小,導致log buffer的數據不能及時進入磁碟。
In Memory Sort >95
值過低表明很多排序都在TEMP表(磁碟)中進行,需要檢查是否有效率過低的SQL,分析sort_area_size是否太小。也有可能是SQL太爛,需要優化SQL,技術上優化不了了就改為優化業務流程。
Soft Parse >95
能夠復用現有執行計劃就是軟解析,不能復用就要重新硬解析。
近似當作SQL在共享區的命中率,通常高,代表使用了綁定變數, 如果低於80%意味著大量硬解析,SQL沒有被有效的重用,需要調整應用使用綁定變數,或者設置cursor sharing參數。
4 內存使用情況
資料庫的內存大小對性能的影響往往比CPU的多少還要重要。
因此需要關注操作系統分給Oracle多少內存(memory target),以及Oracle內部各個內存區域的使用情況。
儘管Oracle11g之後內存默認是自動管理的,但我們了解內存自動變化的情況,對性能分析也有幫助,另外有些用戶還是習慣用採用手工方式進行內存區域的劃分,劃分的是否合理,也可以從內存使用的情況來檢查。
memory_target:操作系統分給Oracle多少內存,可以從v$parameter中查到:
select name,value,display_value from v$parameter;
sga_target:SGA區域的大小,如果=0,則系統自動分配。
pga_aggregate_target:PGA區域大小,如果=0,則系統自動分配。
其他內存參數如db_cache_size、shared_pool_size也類似。
假如內存採用了默認的自動管理方式,我們關注的不僅僅是大小,還有在測試過程中的變化趨勢。所有的項目都有Begin時的大小和End時的大小,關注其變化趨勢。
如果某個區域有明顯變大的趨勢,說明對這個區域的需求量比較大,而初始的值比較小,Oracle在運行過程中慢慢的調整它。
但Oracle的調整並不是實時的,也不一定能把各個內存區域的配比調到性能最優狀態(況且還會有Oracle自身的bug)。
本人有一次測試,資料庫性能非常差,測了好幾次都沒有好轉。測試環境為一個Oracle RAC,每台實例分給Oracle 8G內存,測試過程中並沒有發現哪個內存區域有逐漸增長的趨勢,但發現DB1的Buffer Cache是320M,DB2的Buffer Cache是864M,而大部分業務跑在DB1上。果斷手工修改(其實耗了我周六周日2天時間琢磨AWR)DB1和DB2的Buffer Cache=2G。整個場景的響應時間從20分鐘變為了3分鐘。這個例子說明,自動管理內存不一定能達到性能最優,但有時可以藉助它來分析問題。
內存advisory
內存的advisory也是值得一看的。可以從中看看目前的內存夠不夠用。畢竟一個項目上線之前,誰都不知道它會吃多少內存,或者吃某個區域多少內存,測試環境可能內存還是打折的,遇到性能緩慢是不是由內存不足引起的呢?
關注Main Report>Advisory Statistics,可以看到好多區域的advisory
以SGA為例
可以看到SGA設置為多少M的情況下,對應的DB Time是多少,物理讀是多少。由此可以初步判斷當前的內存設置是不是合理。
TAG:性能測試與調優 |