【MySQL調優】性能測試Benchmark與性能剖析profiling

針對數據庫的優化行爲,需要先進行測量,測量之後,要對測量結果進行分析。這就需要benchmark和profiling。

benchmark可以用到多種工具。

性能剖析-Profiling

profiling需要我們有足夠多的知識和經驗。
對於性能的定義:完成某件任務所需要的時間度量,簡單的說就是響應時間。
而這個時間可以分爲執行時間與等待時間。
執行時間反應的是一條查詢爲什麼會執行那麼長時間,而等待時間則是需要弄清楚究竟這個任務在哪裏被阻塞了這麼久。

性能剖析(profiling)一般有兩個步驟:
1.測量任務花費時間
2.對測量結果進行統計和排序,將重要的任務放在前面

對任務進行分組和分析,生成profile report分析報告。
理想的性能優化會在數據庫系統中建立一系列的測量點,而大部分時候我們都是通過外部去對系統進行測量(黑盒)。

可以通過pt-query-digest來對系統進行剖析,同時得到有意義的聚合結果。
同時,需要對查詢進行聚合,用戶一系列的連續性操作行爲可以聚合成一個更大的操作,然後對這個操作性能進行分析也是十分有價值的。
比如New Relic工具就可以帶來很好的應用程序性能分析功能。

對MySQL查詢進行剖析:

對查詢性能的剖析可以從兩個角度展開:整個服務器負載、針對單條查詢語句的剖析。

服務器負載剖析:

對與服務器負載的剖析,可以使用MySQL查詢日誌。比如設置mysql慢查詢日誌的閾值爲0。
當然可以對通用日誌進行分析,這些通用日誌可以被記錄在數據表中,多數情況下分析通用日誌沒什麼必要。
Percona Server的慢查詢日誌更爲詳細
當權限不足無法進行日誌寫入時,可以使用–processlist不斷查看PROCESSLIST或者通過tcpdump的形式抓取數據包,然後用pt-query-digest --type=tcpdump來分析抓包內容。
獲取了服務器查詢日誌之後,就需要對這些日誌進行分析。
針對峯谷型服務,可以對負載峯值的時間段進行分析,而如果業務比較穩定,就可以隨便選取一分鐘來進行分析。
可以使用pt-query-digest來直接對慢查詢日誌進行分析,分析工具將會爲我們提供有意義的統計分析結果。
針對最差的報告,我們開可以詳細展開,去看它的執行的詳細情況。
工具還爲我們準備好了典型sql的explain代碼,直接複製拷貝出來就可以在mysql中運行然後查看執行計劃

單條查詢語句剖析:

SHOW PROFILE:

首先需要設置會話級別的分析開始:
SET profiling = 1;
這時候執行一條sql語句就會被記錄下來,然後通過
SHOW PROFILE;
的命令就可以查看詳細的剖析結果。
這時候得到的結果沒有經過排序,也可以通過直接查詢INFORMATION_SCHEMA數據表來獲得格式化的數據結果。

SHOW STATUS:

這是一個有用的工具,但並不是一款剖析工具。大部分的結果都是一個計數器,展示了某些活動的頻繁程度,而沒有辦法詳細展示消耗的時間。

慢查詢日誌:

Percona Server提供了詳細的慢查詢日誌的信息,包含show profile和show status的全部輸出。

使用Performance Schema:

目前的一些限制使得performance schema還沒辦法成爲一個通用的性能剖析工具
對於大部分用戶來說,直接看performance schema中的裸數據需要過多的先驗知識和底層原理的理解。

診斷間歇性問題

針對間歇性問題的診斷,儘量不要採用試錯的方式,耗費大量時間且得不償失,並且帶來很大的線上風險。
對於間歇性問題的診斷,首先要判斷是單條查詢的問題還是服務器的問題
如果是服務器所有的查詢都變慢,可以優先考慮是服務器整體存在性能問題,而當只有部分查詢出現變慢的情況,就要開始考慮是不是單條的查詢存在問題了,這裏介紹幾種診斷的方法:

使用SHOW GLOBAL STATUS:

通過高頻率(比如說每秒)執行show global status的方式,收集數據然後分析結果,耗時長但對服務器的壓力負載比較小。可以在服務器上長時間執行,並將最後的結果繪製出來,用來發現出現問題的原因。

使用SHOW PROCESSLIST:

持續不斷的show processlist可以幫助我們觀察是否存在大量線程處於不正確的狀態或者有其他不正常的特徵。

tips:通過\G可以垂直輸出結果,有助於我們後期通過sort|uniq|sort的方式統計某一列值出現的次數。
除此之外,使用INFORMATION_SCHEMA中的PROCESSLIST表或者innotop工具也可以很好的幫助我們實現類似的功能。

使用慢查詢日誌:

在全局設置long_query_time爲0就可以將所有的查詢都記錄下來,這可能需要重製所有的連接來保證這項修改已經生效。
當無法直接修改long_query_time的時候,也可以使用tcpdump+pt-query-digest來實現類似的功能。
一項查詢,是在它已經完成了之後纔會被寫入慢查詢日誌,所以如果出現查詢堆積,就會造成大量的查詢處於完成階段。
理解發現的問題:
通過gunplot或者R等工具,將以上採集到的大量日誌通過圖表的形式展示出來,這有助於我們更快的發現異常時間點,定位相關問題。
通過上面的步驟,我們能夠收集儘可能多的日誌信息,找到問題的時間點,在這之後呢?我們就需要捕獲可以用於診斷的數據。這樣的收集要儘可能的多,寧可多收集一千條正確數據,也不要放過一條錯誤的數據。
這裏我們就需要一個很好的診斷觸發器以及一個數據收集的工具。

診斷觸發器:

診斷觸發器就是要找到一些能在異常場景下與正常場景的某些閾值進行區分的指標。
合理的閾值將會保證在正常場景下不會被觸發(誤報),同時異常場景下不會被忽視(漏報)。
針對這種情況,我們可以自己編寫腳本來實現監控觸發器,或者直接使用pt-stalk。
需要收集什麼樣的數據?
明確了工具之後,我們就要來看一下哪些數據值得被收集
原則上就是在需要的時間段內儘可能多的進行收集
在GNU/Linux平臺,可以使用oprofile,或者strace來分析服務器的系統調用。
對於剖析查詢收集而言,使用tcpdump抓取mysql流量也是個不錯的選擇
對於等待分析,最常用的辦法是GDB的堆棧跟蹤。pt-pmp工具也可以完成類似的工作。
pt-collect可以用於加速我們的分析工作。

解釋結果

對於結果的解釋從兩方面開始入手:確認問題是否真正發生和尋找明顯的跳躍性變化。
對於結果的解釋,尤其是針對操作系統和mysql底層的解釋,需要非常多MySQL和InnoDB的源碼知識,普通用戶很難在這些分析的結果裏推斷出合理的解釋。

性能優化有兩個需要明確認識到的點:
1. 不要把原因和結果進行混淆
2. 在確認問題之前不要隨便嘗試改動系統企圖修復問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章