第五部分 性能調優與架構篇
本篇將爲讀者介紹性能調優的一些背景知識和理論,而後介紹一些工具的運用,最後介紹從應用程序到操做系統、到數據庫、到存儲各個環節的優化。
性能調優是一個高度專業的領域,它須要必定的方法論作指導,咱們須要有必定的背景知識和方法論作引導,才能提出正確的問題,
正確的問題每每意味着有解決問題的可能性,這也是咱們在處理各類事務的時候最難知道的。
提出正確的問題是一種能力,也是能夠訓練出來的。
本篇將花大量篇幅敘述各類調優方法,並分享筆者從業多年來的一些經驗和意識,目的是和你們溝通有無,啓發你們更有效率、更智能地解決性能問題。
本書將主要側重於如何解決問題,而不會深刻講解理論,現實中,你們主要仍是依賴經驗法則,較少用到理論。
可是,一些通用的理論,你們有必要熟悉。
做爲DBA,性能調優不該該是咱們的主要工做,若是對此不是特別有興趣,那麼只要清楚咱們所要掌握的能解決問題的知識就能夠了。
平常運維中,如何保證不出現性能問題,或在性能問題出現以前就將隱患處理掉,纔是更值得看重的,對於運行良好的系統,不存在各類高難度的問題要你去處理。
因爲架構和性能優化的相關性很大,所以也合併在本篇一併講述。 php
第16章 基礎理論和工具
本章首先講述性能調優的一些概念和理論,而後介紹一些工具的使用,最後介紹一些性能調優的方法。
16.1 性能調優理論
16.1.1 基礎概念
對於一些概念,可能不一樣的人有不一樣的解釋,基本上沒有一個很嚴格的標準答案,
筆者將在此闡釋我的理解的一些基本概念,以方便你們在閱讀本書時,對照概念,理解我所講述的內容。
資源(resource):物理服務器的功能組件,一些軟件資源也能夠被衡量,好比線程池、進程數等。
系統的運行,須要各類資源,對於資源列表的肯定,咱們能夠憑藉對系統的瞭解來肯定,也能夠經過繪製系統的功能塊圖的方式來肯定要衡量的資源。
常見的物理資源以下所示。
CPU、CPU核數(core)、硬件線程(hardwarethread)、虛擬線程(virtualthread)
內存 、網絡接口、存儲設備、存儲或網絡的控制器、內部高速互聯
負載 (load):有多少任務正在施加給系統,也就是系統的輸入,要被處理的請求。對於數據庫來講,負載就包括了客戶端段發送過來的命令和查詢。
負載若是超過了設計能力,每每會致使性能問題。
應用程序可能會由於軟件應用的配置或系統架構致使性能下降,
好比,若是一個應用程序是單線程的,那麼無疑它會受制於單線程架構,由於只能利用一個核,後續的請求都必須排隊,不能利用其餘的核。
但性能降低也可能僅僅是由於負載太多了。負載太多將致使排隊和高延時,
好比,一個多線程應用程序,你會發現全部的CPU都是忙碌的,都在處理任務,這個時候,仍然會發生排隊,系統負載也會很高,這種狀況極可能是施加了太高的負載。
若是在雲中,你也許能夠簡單地增長更多的節點來處理太高的負載,在通常的生產應用中,簡單地增長節點有時解決不了問題,你須要進行調優和架構迭代。
負載能夠分紅兩種類型:CPU密集型(CPU-bound)和I/O密集型(I/O-bound)。
CPU密集型指的是那些須要大量計算的應用,它們受CPU資源所限制,也有人稱爲計算密集型或CPU瓶頸型。
I/O密集型指的是那些須要執行許多I/O操做的應用,例如文件服務器、數據庫、交互式shell,它們指望更小的響應時間。它們受I/O子系統或網絡資源所限制。
對於CPU密集型的負載,能夠檢查和統計那些CPU運算的代碼,對於I/O密集型的負載,能夠檢查和統計那些執行I/O操做最多的代碼。這樣就能夠更有針對性地進行調優。
咱們能夠使用系統自帶的工具或應用程序本身的性能檢測工具來進行統計和分析。
對於吞吐率,很顯然,數據庫支持的簡單查詢的吞吐率會比複雜查詢的吞吐率大得多,其餘應用服務器也是相似的,簡單的操做執行得更快,
因此對於吞吐, 咱們也須要定義咱們的系統應處理何種負載。
利用率(utilization):利用率用於衡量提供服務的資源的忙碌程度,它是基於某一段時間間隔內,系統資源用於真正執行工做的時間的百分比。
即, 利用率=忙的時間/總計時間
利用率能夠是基於時間的,好比CPU的利用率:某顆CPU的利用率或總體系統的CPU利用率。好比對於磁盤的利用率,咱們能夠使用iostat命令檢查%util。
利用率也能夠是基於容量的,它能夠表示咱們的磁盤、內存或網絡的使用程度,好比90%的磁盤空間被使用,80%的內存被使用,80%的網絡帶寬被使用等。
能夠用高速公路收費站的例子來進行類比。 利用率表現爲當前有多少收費亭正在忙於服務。
利用率100%,就表示全部的收費亭都正在處理收費,你找不到空閒的收費亭,所以你必須排隊。
那麼在高峯時刻,可能許多時候都是100%的利用率,但若是給出全天的利用率數據,也許只有40%,那麼若是隻關注全天的這個利用率數據就會掩蓋一些問題。
每每利用率的高位會致使資源飽和。利用率100%每每意味着系統有瓶頸,能夠檢查資源飽和度和系統性能加以肯定。
該資源不能提供服務的程度被標識爲它的飽和度,後文有資源飽和度的詳細解釋。
若是是檢測的粒度比較大,那麼極可能就會掩蓋了偶爾的100%的峯值,一些資源,如磁盤,在60%的利用率的時候,性能就開始變差了。
響應時間(responsetime):也叫延遲,指操做執行所須要的耗時,它包括了等待時間和執行時間。
優化執行時間相對簡單,優化等待時間則複雜多了,由於要考慮到各類其餘任務的影響,以及資源的競爭使用。
對於一個數據庫查詢,響應時間就包括了從客戶端發佈查詢命令到數據庫處理查詢,以及傳輸結果給客戶端的全部時間。
延遲能夠在不一樣的環節進行衡量,好比訪問站點的裝載時間,包括DNS延遲、TCP鏈接延遲和TCP數據傳輸時間。
延遲也能夠在更高的級別進行理解,包括數據傳輸時間和其餘時間,好比從用戶點擊連接到網頁內容傳輸,並在用戶的電腦屏幕上渲染完畢。
延遲是以時間作量度來衡量的,能夠很方便地進行比較,其餘的一些指標則不那麼容易衡量和比較,好比IOPS,你能夠將其轉化爲延遲來進行比較。
通常狀況下,咱們衡量性能主要是經過響應時間,而不是使用了多少資源,
優化本質上是在必定的負載下,儘量地減小響應時間,而不是減小資源的佔用,好比下降CPU的使用,資源的消耗只是一個現象,而不是咱們優化的目標。
若是咱們可以記錄MySQL在各個環節所消耗的時間,那麼咱們就能夠有針對性地進行調優,
若是咱們能夠將任務細分爲一些子任務,那麼咱們就能夠經過消除子任務、減小子任務的執行次數或讓子任務執行得更有效率等多種手段來優化MySQL。
伸縮性(scalability):對於伸縮性,有兩個層面的意思。
一是,在資源的利用率不斷增長的狀況下,響應時間和資源利用率之間的關係,當資源利用率升高時,響應時間仍然可以保持穩定,
那麼咱們就說它的伸縮性好,可是若是資源利用率一旦升高,響應時間就開始劣化,那麼咱們就認爲其伸縮性不佳。
二是,伸縮性還有一層意義,表徵系統不斷擴展的能力,系統經過不斷地增長節點或資源,處理不斷增加的負載,同時依然可以保持合理的響應時間。
吞吐率(throughput):處理任務的速率。對於網絡傳輸,吞吐率通常是指每秒傳輸的字節數,對於數據庫來講,指的是每秒查詢數(QPS)或每秒事務數。
併發(concurrency):指的是系統可以並行執行多個操做的能力。若是數據庫可以充分利用CPU的多核能力,那麼每每意味着它有更高的併發處理能力。
容量(capacity):容量指的是系統能夠提供的處理負荷的能力。咱們在平常運維中有一項很重要的工做就是容量規劃,
即確保隨着負荷的增加,咱們的系統仍然可以處理負荷,確保服務良好和穩定。
容量也指咱們的資源使用極限,好比咱們的磁盤空間佔用,在磁盤空間到達必定的閾值後,咱們可能還要考慮擴容。
飽和(saturation):因爲負荷過大,超過了某項資源的服務能力稱爲飽和。飽和度能夠用等待隊列的長度來加以衡量,或者用在隊列裏的等待時間加以衡量。
超過承載能力的工做每每處於等待隊列之中或被返回錯誤,
好比CPU飽和度可用平均運行隊列(runq-sz)來衡量,好比能夠使用iostat命令輸出的avgqu-sz指標衡量磁盤飽和度。
好比內存飽和度能夠用交換分區的一些指標來衡量。
資源利用率高時,可能會出現飽和,圖16-1是一個資源利用率、負載、飽和之間關係的說明圖,
在資源利用率超過100%後,任務不能立刻被處理,須要排隊,飽和度就開始隨着負載的增長線性增加。
飽和將致使性能問題,由於新的請求須要排隊,須要時間進行等待。
飽和並不必定要在利用率100%的時候纔會發生,它取決於資源操做的並行度。
飽和不必定能被發現,生產環境監控系統、監控腳本時存在一個容易犯的錯誤,那就是採樣的粒度太粗,
好比每隔幾分鐘進行採樣,可能就會發現不了問題, 但問題卻會發生在短期的幾十秒內。
忽然的利用率的高峯也很容易致使資源飽和,出現性能問題。
咱們須要熟悉以上概念,並瞭解它們之間的關係,通常來講,隨着負荷的上升,吞吐率也將上升,吞吐曲線開始時會一直是線性的,
咱們的系統響應時間在開始的一個階段會保持穩定,可是到達某個點後,性能就會開始變差,響應時間變得更長,
之後隨着負荷的繼續增長,此時咱們的吞吐率將不能再繼續增加,甚至還會降低,而響應時間也可能會變得不可接受。
有一種例外狀況是,應用服務器返回錯誤狀態碼,好比Web服務器返回503錯誤,因爲基本上不消耗資源,難以到達極限,因此返回錯誤碼的吞吐曲線會保持線性。
對於性能的見解其實比較主觀,一個性能指標是好仍是壞,可能取決於研發人員和終端用戶的指望值。
因此,若是咱們要判斷是否應該進行調優,那麼咱們須要對這些指標進行量化,當咱們量化了指標,肯定了性能目標時,這樣的性能調優才更科學,才更容易被理解和溝通一致。
如下將簡要敘述三個基礎理論:阿姆達爾定律、通用擴展定律和排隊論。 node
16.1.2 阿姆達爾定律
阿姆達爾定律(Amdahl’s law)是計算機科學界的一項經驗法則,因IBM公司的計算機架構師吉恩·阿姆達爾而得名。
吉恩·阿姆達爾在1967年發表的論文中提出了這個重要定律。
阿姆達爾定律主要用於發現當系統的部分組件獲得改進,總體系統可能獲得的最大改進。
它常常用於並行計算領域,用來預測應用多個處理器時理論上的最大加速比。
在性能調優領域,咱們利用此定律有助於咱們解決或緩解性能瓶頸問題。
阿姆達爾定律的模型闡釋了咱們在現實生產中串行資源爭用時候的現象。
圖16-2分別展現了線性擴展(linear scaling)和按阿姆達爾定律擴展的加速比 (speedup)。
在一個系統中,不可避免地會有一些資源必需要串行訪問,這就限制了咱們的加速比,
即便咱們增長了併發數(橫軸),但取得的效果並不理想,難以得到線性擴展的能力(圖16-2中的直線)。
如下介紹中,系統、算法、程序均可以看做是優化的對象,筆者在此不會加以區分,它們都有串行的部分和能夠並行的部分。
在並行計算中,使用多個處理器的程序的加速比受限制於程序串行部分的執行時間。
例如,若是一個程序使用一個CPU核執行須要20個小時,其中的部分代碼只能串行,須要執行1個小時,其餘19小時的代碼執行能夠並行,
那麼,若是不考慮有多少CPU可用來並行執行程序,最小的執行時間也不會少於1個小時(串行工 做的部分),所以加速比被限制爲最多20倍(20/1)。
加速比越高,證實優化效果越明顯。
阿姆達爾定律能夠用以下公式表示: S(n) = T(1)/T(n) = T(1)/T(1)[B+(1-B)/n] =1/[B+(1-B)/n]
其中,
S(n):固定負載下,理論上的加速比。
B:串行工做部分所佔比例,取值範圍爲0~1。
n:並行線程數、並行處理節點個數。
以上公式具體說明以下。
加速比=沒有改進前的算法耗時T(1)/改進後的算法耗時T(n)。
咱們假定算法沒有改進以前,執行總時間是1(假定爲1個單元)。
那麼改進後的算法,其時間應該是串行工做部分的耗時(B)加上並行部分的耗時(1-B)/n,因爲並行部分能夠在多個CPU核上執行,因此並行部分實際的執行時間是(1-B)/n
根據這個公式,若是並行線程數(咱們能夠理解爲CPU處理器數量)趨於無窮,那麼加速比將與系統的串行工做部分的比例成反比,
若是系統中有50%的代碼須要串行執行,那麼系統的最大加速比爲2。
也就是說,爲了提升系統的速度,僅增長CPU處理器的數量不必定能起到有效的做用,須要提升系統內可並行化的模塊比重,
在此基礎上合理增長並行處理器的數量,才能以最小的投入獲得最大的加速比。
下面對阿姆達爾定律作進一步說明。阿姆達爾這個模型定義了固定負載下,某個算法的並行實現相對串行實現的加速比。
例如,某個算法有12%的操做是能夠並行執行的,而剩下的88%的操做不能並行,那麼阿姆達爾定律聲明,最大加速比是1/(1-0.12)=1.136。
如上公式中的n趨向於無窮大,那麼加速比S=1/B=1/(1- 0.12)。
再例如,對於某個算法,能夠並行的比例是P,這部分並行的代碼可以加速S倍(S能夠理解成CPU核的個數,即新代碼的執行時間爲原來執行時間的1/S)。
若是此算法有30%的代碼能夠被並行加速,即P等於0.3,這部分代碼能夠被加速2倍,即S等於2。那麼,使用阿姆達爾定律計算其整個算法的加速好比下。
1/[B+(1-B)/n]=1/[(1-0.3)+0.3/2]=1.176
以上公式和前一個公式是相似的,只是前一個公式的分母是用串行比例B來表示的。
再例如,某項任務,咱們能夠分解爲4個步驟,P一、P二、P三、P4,執行耗時佔總耗時百分比分別是11%、18%、23%和48%。
咱們對它進行優化,P1不能優化,P2能夠加速5倍,P3能夠加速20倍,P4能夠加速1.6倍。
那麼改進後的執行時間計算以下。0.11/1+0.18/5+0.23/20+0.48/1.6=0.4575
總的加速比是1/0.4575=2.186。咱們能夠看到,雖然有些部分加速比有20倍,有些部分有5倍,但總的加速比並不高,略大於2,由於佔時間比例最大的P4部分僅僅加速了1.6倍。
圖16-3演示了並行工做部分的比例不一樣時的加速比曲線,
咱們能夠觀察到,加速比受限制於串行工做部分的比例,當95%的代碼均可以進行並行優化時,理論上的最大加速比會更高,但最高不會超過20倍。
阿姆達爾定律也用於指導CPU的可擴展設計。CPU的發展有兩個方向,更快的CPU或更多的核。
目前看來發展的重心偏向了CPU的核數,隨着技術的不斷髮展,CPU的核數在不斷地增長,目前咱們的數據庫服務器配置四核、六核都已經比較常見了,
但有時咱們會發現雖然擁有更多的核,當咱們同時運行幾個程序時, 只有少數幾個線程處於工做中,其餘的並未作什麼工做。
實踐當中,並行運行多個線程每每並不能顯著地提高性能,程序每每並不能有效地利用多核。
在多核處理器中加速比是衡量並行程序性能的一個重要參數,可否有效下降串行計算部分的比例和下降交互開銷決定了可否充分發揮多核的性能,
其中的關鍵在於:合理劃分任務、減小核間通訊。 mysql
16.1.3 通用擴展定律
可擴展性指的是,咱們經過不斷地增長節點來知足不斷增加的負載需求,這樣的一種能力。
但是,不少人提到了可擴展性,卻沒有給它一個清晰的定義和量化標準。
實際上,系統可擴展性是能夠被量化的,若是你不能量化可擴展性,你就不能確保它可以知足須要。
USL(universal scalability law,通用擴展定律)就提供了一 種方式,讓咱們能夠量化系統的可擴展性。
USL,即通用擴展定律,由尼爾·鞏特爾博士提出,相對比阿姆達爾定律,USL增長了一個參數β表示「一致性延遲」(coherency delay)。
圖16-4是它的模型圖,縱軸表示容量,橫軸表示併發數。
USL能夠用以下公式進行定義:C(N)=N/[1+α((N-1)+βN(N-1))]
其中, C(N):容量。 0≤α,β<1。
α:Contention,爭用的程度,因爲等待或排隊等待共享資源,將致使不能線性擴展。
β:Coherency,一致性延遲的程度,因爲節點之間須要交互以使數據保持一致,所以會帶來延遲。
爲了維持數據的一致性,將致使系統性能惡化,即隨着N的上升,系統吞吐率反而會降低。當這個值爲0時,咱們能夠將其看做是阿姆達爾定律。
N:Concurrency,併發數,理想狀況下是線性擴展的。若是是衡量軟件的可擴展性,那麼N能夠是客戶端/用戶併發數,
在固定的硬件配置下(CPU數不變),不斷增長客戶端/用戶,以獲取性能吞吐模型,咱們的壓力測試軟件,如LoadRunner、sysbench即爲此類。
若是是衡量硬件的可擴展性,那麼N能夠是CPU的個數,咱們不斷增長CPU的個數,同時保持每顆CPU上的負載不變,
即若是每顆CPU施加100個用戶的負載,每增長一顆CPU,就增長100個用戶,那麼一臺32個CPU的機器,須要3200個用戶的併發負載。
下面咱們來看看圖16-5到圖16-8所示的4個圖,對應在不一樣負載下容量(吞吐能力)的變化。
圖16-5中,α=0、β=0,此時,隨着負載的升高,系統吞吐是線性上升的,即咱們所說的線性擴展,這是很理想化的一種狀況,
每份投入必然會得到等值回報, 但很難無限進行下去,性能模型的前面部分可能會表現爲線性擴展。
圖16-6中,α>0、β=0,此時對於共享資源的爭用將致使性能曲線再也不線性增加。
圖16-7中,α>>0、β=0。此時共享資源的爭用大大增長,咱們將看到一種「收益遞減」的現象,即咱們的持續投入資源(好比金錢)變大,可是所取得的收益都越 來越小。
圖16-8中,α>>0、β>0。此時β參數開始影響咱們的性能曲線,咱們除了共享資源的爭用,還須要應對系統內各個節點的通訊、同步狀態的開銷。此時性能曲線 將會變差,回報趨向於負值。
USL應用很廣,如壓力測試工具結果分析,對磁盤陣列、SAN和多核處理器及某些類型的網絡I/O建模,分析內存顛簸、高速緩存未命中致使的延時等場景。
因爲它的應用範圍很廣,因此也稱之爲通用擴展定律。
USL一些具體的應用場景以下。
(1)模擬壓力測試
如下例子,如圖16-9所示,將不斷增長虛擬用戶(橫軸表示的Virtual users),記錄其吞吐率(縱軸表示的Throughput),而後經過繪製的圖形獲得性能吞吐的模型。
(2)檢測錯誤的測量結果
有時咱們進行測試,會發現咱們的測量輸出結果不符合模型,這時咱們須要審視下,是否咱們的測量方式存在問題或受到了其餘因素的干擾?
須要找出是什麼緣由致使的非預期的行爲。
(3)性能推斷
若是擴展性不好,咱們能夠經過公式和圖得知是α(對共享資源的爭用)仍是β(一致性延遲)應該承擔更大的責任。
(4)性能診斷
USL公式雖然簡單易用,但普通人也許沒法從中找到解決問題的思路和方法。由於全部的信息都被濃縮爲2個參數α和β。
然而,應用程序開發者和系統架構師可能依據這些信息,就能輕易地找到問題癥結所在。
(5)對生產環境收集的性能數據進行分析
對生產環境的性能數據(圖形)進行分析,可讓咱們肯定合適的工做負載(好比並發線程數、CPU個數)。
(6)「擴展區」(scalability zone)概念的應用
咱們看下圖16-10,咱們繪製不一樣場景下的性能曲線,這些曲線定義了可擴展區域Async msging、Sync waiting、Syncthrashing。
程序的性能點圖跨越了多個區域。
在超過15個併發的時候,性能曲線進入另一個區域Sync waiting,擴展性變差,這是由於「同步排隊」(synchronous queueing)的影響所致使的。 linux
16.1.4 排隊論
(1)排隊論的歷史
排隊論(queueing theory)起源於20世紀初的電話通話。
Agner Krarup Erlang,一個在丹麥哥本哈根電話交換局工做的工程師,
經過研究人們打電話的方式,發明了人們須要等待多久的公式,厄朗發表了一篇著名的文章「自動電話交換中的機率理論的幾個問題的解決」。
隨着之後的發展,排隊論成爲數學中一門重要的學科,20世紀50年代初,大衛·坎達(David G.Kendall)對排隊論作了系統的研究,使排隊論獲得了進一步的發展。
(2)定義
排隊論也稱爲隨機服務系統理論、排隊理論,是數學運籌學的分支學科。它是研究服務系統中排隊現象隨機規律的學科。
排隊論普遍應用於電信、交通工程、 計算機網絡、生產、運輸、庫存等各項資源共享的隨機服務系統和工廠、商店、辦公室、醫院等的設計。
排隊是咱們每一個人都很熟悉的現象。由於爲了獲得某種服務必須排隊。
有一類排隊是有形的,例如在售票處等待買票的排隊,加油站前汽車等待加油的排隊等;
還有一類排隊是無形的,例如電話交換機接到的電話呼叫信號的排隊,等待計算機中心處理機處理的信息的排隊等。
爲了敘述的方便,排隊者不管是人、物或信息,之後都統稱爲「顧客」。
服務者不管是人或事物,例如一臺電子計算機也能夠是排隊系統中的服務者,之後都統稱爲「服務檯」。
排隊現象是咱們不但願出現的現象,由於人在排隊至少意味着是在浪費時間;物的排隊則說明了物資的積壓。可是排隊現象卻沒法徹底消失,這是一種隨機現象。
顧客到達間隔時間的隨機性和爲顧客服務時間的隨機性是排隊現象產生的主要緣由。
若是上述的兩個時間都是固定的,那麼咱們就能夠經過妥善安排來徹底消除排隊現象。
排隊論是研究排隊系統在不一樣的條件下(最主要的是顧客到達的隨機規律和服務時間的隨機規律)產生的排隊現象的隨機規律性。
也就是要創建反映這種隨機性的數學模型。研究的最終目的是爲了運用這些規律,對實際的排隊系統的設計與運行作出最優的決策。
(3)排隊論的通常模型
圖16-11是排隊論的通常模型圖。
其中,服務檯用於服務隊列中的顧客,能夠多個服務檯併發工做。
圖16-11中的排隊系統,各個顧客從顧客源出發,隨機地來到服務機構,按必定的排隊規則等待服務,直到按必定的服務規則接受服務後離開排隊系統。
對於一個服務系統來講,若是服務機構太小,以至不能知足要求服務的衆多顧客的須要,那麼就會產生擁擠現象而使服務質量下降。
所以,顧客老是但願服務機構越大越好,可是,若是服務機構過大,人力和物力方面的開支就會相應地增長,從而就會形成浪費,
所以研究排隊模型的目的就是要在顧客須要和服務機構的規模之間進行權衡和決策,使其達到合理的平衡。
(4)理論概括
在計算機領域,許多軟硬件組件均可以模型化爲排隊系統。咱們能夠使用排隊理論分析排隊現象,分析隊列的長度、等待時間、利用率等指標。
排隊理論基於許多數學和統計理論,好比機率理論、隨機過程理論、Erlang-C公式(Erlangs C formula)、李特爾法則。
如下簡單介紹排隊論的一些理論。詳細的內容可參考NeilJ.Gunther的圖書《The PracticalPerformance Analyst》。
李特爾法則(Little’s law)
李特爾法則能夠用以下公式來表示。 L=λW
這個公式定義了一個系統中的平均訪問請求數=平均到達速率×平均服務時間
好比,咱們有一個系統,平均到達速率是10000次請求/s,每一個請求須要花費0.05s來處理,即平均服務時間爲0.05s,
那麼根據李特爾法則,服務器在任什麼時候刻都將承擔10000×0.05=500個請求的業務處理。
若是過了一段時間,因爲客戶端流量的上升,併發的訪問速率達到了20000次請求/s,這種狀況下,咱們該如何改進系統的性能呢?
根據李特爾法則,咱們有以下兩種方案。
1)提升服務器的併發處理能力,即20000×0.5=1000。
2)減小服務器的平均服務時間,即W=L/λ=500/20000=0.025s。
排隊論表示法
咱們能夠用肯德爾表示法(Kendall’s notation)來對排隊系統進行分類,肯德爾表示法可以使用以下的簡化形式: A/S/m
其中, A:到達的規則,即到達的時間間隔的分佈,多是隨機的、肯定型的或泊松分佈等其餘分佈方式。
S:服務規則,即指服務時間的分佈,多是固定的或指數的等其餘分佈方式。
m:服務檯個數,一個或多個。
表示顧客到達的間隔時間和服務時間的分佈經常使用的約定符號分別以下。
M:指數分佈,在機率論和統計學中,指數分佈(ExponentialDistribution)是一種連續機率分佈。
指數分佈能夠用來表示獨立隨機事件發生的時間間隔,好比旅客進機場的時間間隔、中文維基百科新條目出現的時間間隔,等等。
D:肯定型(Deterministic)。
G:通常(General)服務時間的分佈。
一些常見的排隊系統模型具體以下。
M/M/1:表示顧客相繼到達的間隔時間爲指數分佈、服務時間爲指數分佈、單服務檯。
M/M/c:表示顧客相繼到達的間隔時間爲指數分佈、服務時間爲指數分佈、多服務檯。
M/G/1:表示顧客相繼到達的間隔時間爲指數分佈、服務時間爲通常服務時間分佈、單服務檯。
M/D/1:表示顧客相繼到達的間隔時間爲指數分佈、服務時間爲肯定型時間分佈、單服務檯。好比咱們的旋轉磁盤可用此模型進行分析。 ios
16.2 診斷工具
咱們須要熟悉Linux下經常使用的診斷性能的工具,確切地說,
咱們須要在平時不使用這些命令的時候,就可以熟練應用它,這樣咱們在實際診斷性能問題的時候,才能夠快速使用它們,而不是事到臨頭纔去學某個命令應該如何使用。
咱們進行性能調優的首要目的是須要找到系統的瓶頸所在。最多見的瓶頸是內存、I/O或CPU。
Linux提供了一系列的工具來檢查系統和查找瓶頸。一些工具揭示了系統的整體健康狀態,一些工具則提供了特定的系統組件信息。
使用這些工具將是一個好的起點,有助於咱們肯定性能調優的方向。
現實中,真正出現性能問題時,每每會有許多現象發生,發現一個現象並不難,難的是定位問題的根源,是什麼因素的影響最大。
當你具有了知識,可以熟練使用各類工具,瞭解數據庫、操做系統、硬件等各類組件的機制,經過檢查各類工具和命令輸出的數據,你對找到問題的根源所在將會愈來愈有經驗。
使用工具要避免只使用本身熟悉的工具,由於工具在不斷地進化中,因此,若是有了更好的工具,那麼花一些學習成本也是值得的。
對於性能的優化,咱們每每有許多種工具能夠選擇,這也會形成一些困擾,由於不一樣工具的功能有重疊,甚至大部分都有重複,
這樣不只浪費了資源,也讓用 戶的學習成本變得更高,由於可能你要熟悉許多工具而不僅是一種。 算法
16.2.1 OS診斷工具
sar、vmstat、iostat都是工具包sysstat(thesystemmonitoring tool)裏的命令,若是你的系統中沒有這些命令,那麼你須要安裝sysstat包。
本節對sar會作比較詳細的介紹,由於其餘命令收集的信息與它相似,所以本節將不對其餘命令作詳細說明,僅僅列出一些須要關注的要點。
1.sar
sar(system activity reporter,系統活動狀況報告)命令是系統維護的重要工具,主要用於幫助咱們掌握系統資源的使用狀況,能夠從多方面對系統的活動進行報告,
報告內容包括:文件的讀寫狀況、系統調用的使用狀況、磁盤I/O、CPU效率、內存使用情況、進程活動及與IPC有關的活動等。
sar經過cron定時調用執行以收集和記錄信息,默認狀況下,Linux每10分鐘運行一次sar命令來收集信息,
若是你認爲時間跨度太長,不容易發現性能問題,你也能夠更改調度任務的間隔,修改/etc/cron.d/sysstat便可。
cat sysstat
# run system activity accounting tool every 10 minutes
*/10 * * * * root /usr/lib64/sa/sa1 1 1
而後重啓crond生效。
/etc/init.d/crond restart
sar命令的經常使用格式以下: sar [ options... ] [ <interval> [ <count> ] ]
sar若是不加參數,則默認是讀取歷史統計信息,你能夠指定interval和count對當前的系統活動進行統計。
其中參數的具體說明以下:interval爲採樣間隔,count爲採樣次數,默認值是1。 sql
[root@bogon sa]# sar --help
Usage: sar [ options ] [ <interval> [ <count> ] ]
Options are:
[ -A ] [ -B ] [ -b ] [ -C ] [ -d ] [ -F [ MOUNT ] ] [ -H ] [ -h ] [ -p ] [ -q ] [ -R ]
[ -r ] [ -S ] [ -t ] [ -u [ ALL ] ] [ -V ] [ -v ] [ -W ] [ -w ] [ -y ]
[ -I { <int> [,...] | SUM | ALL | XALL } ] [ -P { <cpu> [,...] | ALL } ]
[ -m { <keyword> [,...] | ALL } ] [ -n { <keyword> [,...] | ALL } ]
[ -j { ID | LABEL | PATH | UUID | ... } ]
[ -f [ <filename> ] | -o [ <filename> ] | -[0-9]+ ]
[ -i <interval> ] [ -s [ <hh:mm:ss> ] ] [ -e [ <hh:mm:ss> ] ]shell
options爲命令行選項,sar命令經常使用的選項分別以下。
-A:全部報告的總和。
-B:輸出內存使用狀況的統計信息。
-u:輸出CPU使用狀況的統計信息。
-v:輸出inode、文件和其餘內核表的統計信息。
-d:輸出每個塊設備的活動信息,通常添加選項-p以顯示易讀的設備名。
-r:輸出內存和交換空間的統計信息。
-b:顯示I/O和傳送速率的統計信息。
-c:輸出進程的統計信息,每秒建立的進程數。
-R:輸出內存頁面的統計信息。
-y:終端設備的活動狀況。
-w:輸出系統交換活動的信息,即每秒上下文切換次數。
以下是一些sar使用的例子。 數據庫
(1)CPU資源監控
例如,每10s採樣一次,連續採樣3次,觀察CPU的使用狀況,並將採樣結果以二進制的形式存入當前目錄下的文件test中,
須要鍵入以下命令: sar -u -o test 10 3
輸出項說明以下:
CPU:all表示統計信息爲全部CPU的平均值。咱們能夠使用sar-P n查看某顆CPU。
%user:顯示在用戶級別運行和使用CPU總時間的百分比。
%nice:顯示在用戶級別,用於nice操做,所佔用CPU總時間的百分比。
%system:在覈心級別(kernel)運行所佔用CPU總時間的百分比。
%iowait:顯示用於等待I/O操做所佔用CPU總時間的百分比。
%idle:顯示CPU空閒時間所佔用CPU總時間的百分比。
1)若%iowait的值太高,則表示硬盤存在I/O瓶頸。
2)若%idle的值很高但系統響應很慢時,有多是CPU正在等待分配內存,此時應加大內存容量。
3)若%idle的值持續低於10,則系統的CPU處理能力相對較低,代表系統中最須要解決的資源是CPU。 express
(2)查看網絡的統計
語法:sar -n KEYWORD。
KEYWORD經常使用的值及說明具體以下。
DEV:顯示網絡設備統計,如eth0、eth1等。
EDEV:顯示爲網絡設備錯誤統計。
NFS:顯示NFS客戶端活動統計。
ALL:顯示全部統計信息。
以下命令可查看網絡設備的吞吐,數據每秒更新一次,總共更新5次。
[root@localhost ~]# sar -n DEV 1 5
輸出項說明。
第一字段:時間。
IFACE:設備名。
rxpck/s:每秒收到的包。
txpck/s:每秒傳輸的包。
rxkB/s:每秒收到的全部包的體積。
txkB/s:每秒傳輸的全部包的體積。
rxcmp/s:每秒收到的數據切割壓縮的包的總數。
txcmp/s:每秒傳輸的數據切割壓縮的包的總數。
rxmcst/s:每秒收到的多點傳送的包。
能夠使用grep命令對輸出進行過濾,命令以下:sar -n DEV 2 5 | grep eth0
若是想知道網絡設備錯誤報告,也就是用來查看設備故障的,應該用EDEV命令,好比下面的例子:sar -n EDEV 2 5
(3)內存分頁監控
例如,每10s採樣一次,連續採樣3次,監控內存分頁,命令以下:sar -B 10 3
10:45:04 AM pgpgin/s pgpgout/s fault/s majflt/s
10:45:14 AM 606.19 3648.35 13893.21 0.00
10:45:24 AM 626.17 3726.67 525.97 0.00
10:45:34 AM 557.36 3734.53 1.50 0.00
Average: 596.60 3703.17 4810.10 0.00
輸出項說明以下:
pgpgin/s:表示每秒從磁盤或SWAP置換到內存的字節數(KB)。
pgpgout/s:表示每秒從內存置換到磁盤或SWAP的字節數(KB)。
fault/s:每秒鐘系統產生的缺頁數,即主缺頁與次缺頁之和(major+minor)。
majflt/s:每秒鐘產生的主缺頁數,這會致使將數據從磁盤加載到內存,所以須要留意。
pgfree/s:
pgscank/s:
pgscand/s:
pgsteal/s:
%vmeff:
(4)I/O和傳送速率監控
例如,每10s採樣一次,連續採樣3次,須要鍵入以下命令:sar -b 10 3
輸出項說明以下:
tps:每秒鐘物理設備的I/O傳輸總量。
rtps:每秒鐘從物理設備讀入的數據總量。
wtps:每秒鐘向物理設備寫入的數據總量。
bread/s:每秒鐘從物理設備讀入的數據量,單位爲塊/s。
bwrtn/s:每秒鐘向物理設備寫入的數據量,單位爲塊/s。
(5)進程隊列長度和平均負載狀態監控
例如,每10s採樣一次,連續採樣3次,監控進程隊列長度和平均負載狀態,命令以下:sar -q 10 3
輸出項說明以下:
runq-sz:運行隊列的長度(等待運行的進程數)。
plist-sz:進程列表中進程(processes)和線程(threads)的數量。
ldavg-1:最後1分鐘的系統平均負載(systemload average)。
ldavg-5:過去5分鐘的系統平均負載。
ldavg-15:過去15分鐘的系統平均負載。
blocked:
(6)系統交換活動信息監控
例如,每10s採樣一次,連續採樣3次,監控系統交換活動信息,命令以下:sar -W 10 3
輸出項說明以下:
pswpin/s:每秒系統換入的交換頁面(swap page)數量。
pswpout/s:每秒系統換出的交換頁面數量。
(7)設備使用狀況監控
例如,每10s採樣一次,連續採樣3次,報告設備使用狀況,命令以下:sar -d 10 3 -p
其中,參數-p能夠打印出sda、hdc等易讀的磁盤設備名稱,若是不使用參數-p,設備節點則有多是dev8-0、dev22-0這樣的形式。
輸出項說明以下:
tps:每秒從物理磁盤I/O的次數。多個邏輯請求會被合併爲一個I/O磁盤請求,一次傳輸的大小是不肯定的。
rd_sec/s:每秒讀扇區的次數。
wr_sec/s:每秒寫扇區的次數。
avgrq-sz:發送到設備的請求的平均大小,單位爲扇區。
avgqu-sz:磁盤請求隊列的平均長度。
await:從請求磁盤操做到系統完成處理,每次請求的平均消耗時間,包括請求隊列的等待時間,單位是毫秒。
svctm:系統處理每次請求的平均時間,不包括在請求隊列中消耗的時間。
%util:I/O請求佔CPU的百分比,比率越大,說明越飽和。
1)avgqu-sz的值較低時,設備的利用率較高。
2)當%util的值接近100%時,表示設備帶寬已經佔滿。
(8)查看歷史統計信息
有時咱們但願可以看到歷史性能統計信息,能夠進入目錄/var/log/sa,saXX文件是XX日的歷史數據,
能夠使用sar –f saXX 命令查看,例如, sar -f sa17 。默認將顯示成天的數據。
咱們能夠加上-s選項指定特定時間段的數據,例如, sar -q -f sa17 -s 05:00:00 | head -n 10
以上命令將只顯示17日5點以後的load的統計數據,且只顯示最前面的10條記錄。
05:00:01 AM runq-sz plist-sz ldavg-1 ldavg-5 ldavg-15 blocked
05:10:01 AM 0 174 0.00 0.01 0.05 0
05:20:01 AM 0 175 0.00 0.01 0.05 0
Average: 0 174 0.00 0.01 0.05 0
輸出結果與「(5)進程隊列長度和平均負載狀態監控」一致
(9)輸出inode、文件和其餘內核表的統計信息
命令:sar -v 10 3
05:26:28 AM dentunusd file-nr inode-nr pty-nr
05:26:38 AM 85375 1152 37432 1
05:26:48 AM 85375 1152 37432 1
05:26:58 AM 85375 1152 37432 1
Average: 85375 1152 37432 1
輸出項說明以下:
dentunusd:目錄高速緩存中未被使用的條目數量。
file-nr:文件句柄(file handle)的使用數量。
inode-nr:索引節點句柄(inode handle)的使用數量。
要想判斷系統的瓶頸問題,有時須要將幾個sar命令選項結合起來。
懷疑CPU存在瓶頸,可用sar -u和sar -q等來查看。
懷疑內存存在瓶頸,可用sar -B、sar -r和sar -W等來查看。
懷疑I/O存在瓶頸,可用sar -b、sar -u和sar -d等來查看。
2.iostat
iostat是I/O statistics(輸入/輸出統計)的縮寫,iostat工具將對系統的磁盤操做活動進行監視。
它的特色是彙報磁盤活動的統計狀況,同時也將彙報出CPU的使用狀況。
iostat有一個弱點,那就是它不能對某個進程進行深刻分析,只能對系統的總體狀況進行分析。
iostat的語法以下:iostat [ options... ] [ <interval> [ <count> ] ]
Usage: iostat [ options ] [ <interval> [ <count> ] ]
Options are:
[ -c ] [ -d ] [ -h ] [ -k | -m ] [ -N ] [ -t ] [ -V ] [ -x ] [ -y ] [ -z ]
[ -j { ID | LABEL | PATH | UUID | ... } ]
[ [ -T ] -g <group_name> ] [ -p [ <device> [,...] | ALL ] ]
[ <device> [...] | ALL ]
舉例以下:
iostat -x sda 1
iostat -txm 10 3
參數及說明分別以下:
-t:打印彙報的時間。
-x:默認顯示全部設備。
-m:統計信息顯示每秒多少MB而不是默認的每秒多少塊。
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.00 0.00 0.01 0.02 0.00 0.00 34.80 0.00 29.88 52.71 23.03 5.34 0.02
dm-0 0.00 0.00 0.01 0.03 0.00 0.00 31.67 0.00 33.00 64.01 26.35 5.03 0.02
dm-1 0.00 0.00 0.00 0.00 0.00 0.00 49.78 0.00 14.17 14.17 0.00 13.30 0.00
dm-2 0.00 0.00 0.00 0.00 0.00 0.00 69.12 0.00 11.03 11.62 1.00 10.45 0.00
輸出項解析以下:
avgqu-sz:對於在線OLTP業務,應該大概近似於MySQL的頁塊大小,若是你看到這個值遠遠大於你的MySQL實例頁塊(16KB),
那麼可能存在一些其餘的非數據庫I/O負荷,或者你的數據庫由於某些緣由(如預讀)致使檢索數據的效率不高。
svctm:服務時間。
await:平均等待時間。 磁盤I/O請求包含服務時間(svctm)和等待時間(await),svctm通常小於10ms,咱們要重點關注await。
%util:磁盤利用率。 在磁盤利用率達到100%的時候,意味着存在I/O瓶頸,這個時候,I/O達到飽和,此時的吞吐率咱們能夠用以下公式來衡量: (r/s+w/s)*svctm=%util
此時,吞吐率(r/s+w/s)就是svctm的倒數。注意,此公式僅在磁盤利用率達到100%的時候成立。
3.vmstat
vmstat這個工具提供了系統總體性能的報告,它能對進程、內存、頁交換、I/O、中斷及CPU使用狀況進行統計並報告信息。
vmstat的輸出相似以下。
vmstat 2 222
procs -----------memory-------------swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 27724752 1103508 26829932 0 0 0 26 0 0 3 0 96 0 0
2 0 0 27725012 1103508 26829940 0 0 0 136 7293 10504 5 0 95 0 0
1 0 0 27724244 1103508 26830532 0 0 0 4096 7620 11758 6 1 93 0 0
咱們通常關注r、b、id及si、so。
(1)procs部分
r:表示當前有多少進程正在等待運行,若是r是連續的大於在系統中的CPU的個數,則表示系統如今運行得比較慢,有多數的進程正在等待CPU。
b:表示當前有多少進程被阻塞。
(2)memory部分
swpd、free、buff、cache這4項展現了內存是如何使用的,
swap列顯示了swap被使用的數量,
free列顯示了目前空閒的內存,
buffer列顯示了buffer所使用的內 存,
cache列顯示了page cache所使用的內存,cache越大,代表有越多的內存用於cache文件。
(3)swap部分
si:每秒從磁盤交換到swap的內存。
so:每秒從swap交換到磁盤的內存。
si、so正常狀況下應該等於0,若是持續不爲0,那麼極可能存在性能問題。
(4)io部分
bi:從塊設備讀入數據的總量(讀磁盤)。
bo:塊設備寫入數據的總量(寫磁盤)。
bi、bo的變化反映了咱們磁盤讀取和寫入的速率。
(5)system部分
in:每秒中斷次數,包括時鐘。
cs:每秒上下文切換次數。
(6)CPU部分
這些列展現了不一樣CPU完成不一樣任務的CPU時間百分比。
咱們由此能夠得知,CPU是否真正在作事,仍是處於空閒或等待狀態。
很高的sy值,代表可能有過多的 系統調用或系統調用效率不高。
us:運行非內核代碼所花費的時間百分比,即進程在用戶態使用的CPU時間百分比。
sy:運行內核代碼所花費的時間百分比,即進程在系統態使用的CPU時間百分比。
id:空閒的CPU時間百分比。
wa:等待I/O的CPU時間百分比。
st:從虛擬機偷取的CPU時間百分比。
4.oprofile
oprofile是Linux內核支持的一種性能分析機制,是一套低開銷的工具集合,簡單易用,適合於在實際的系統中分析程序的性能瓶頸。
它能夠工做在不一樣的體系結構上,包括MIPS、ARM、IA3二、IA64和AMD。內核2.6的發行版通常都內置了這個工具。
經過oprofile這個工具,開發人員能夠得知一個程序的瓶頸在哪裏,進而指導代碼優化。
oprofile的基本原理是進行抽樣統計,處理器定時中斷,oprofile可在這個時候記錄哪些代碼正在執行。
每每耗時更長的代碼被取樣的次數更多,經過這種方式,咱們能夠發現哪一個可執行程序或哪一個function消耗的CPU最多,進一步分析便可找到可供調優的代碼片斷。
系統的運行,每每就是在處理各類事件,好比CPU指令、磁盤I/O、網絡包、系統調用、庫調用、應用程序事務、數據庫查詢,等等。
性能分析每每和研究這些事件的統計有關,
例如每秒操做的次數、每秒傳輸的字節數、平均延時、有時重要的細節信息在統計中可能會被忽視掉,
這個時候對每類事件單獨進行統計會更有助於你瞭解系統的行爲。
oprofile支持兩種採樣(sampling)方式:基於事件的採樣(eventbased)和基於時間的採樣(timebased)。
基於事件的採樣是oprofile只記錄特定事件的發生次數。這種方式須要CPU內部有性能計數器(performacecounter)。
基於時間的採樣是oprofile藉助OS時鐘中斷的機制,每一個時鐘中斷時oprofile都會記錄一次(採一次樣),
引入此種採樣方式的目的在於提供對沒有性能計數器的CPU的支持,
其精度相對於基於事件的採樣要低,由於要藉助OS時鐘中斷的支持,對禁用中斷的代碼oprofile不能對其進行分析。
雖說基於事件的方法在理論上更精確,但在大部分簡單的場景下,基於時間的方法也能工做得很好,
因此,若是你的CPU在基於事件的性能診斷中存在異常的狀況,那麼就使用基於時間的方法好了。
許多人不知道如何有效地使用oprofile來進行性能優化,這裏將介紹一些基本的用法。
爲了及時反映軟硬件的發展,支持不一樣的CPU,oprofile版本更新得比較頻繁,目前版本(截至2014年10月6日)是1.0.0版本。
因爲主要的發行版內置的oprofile通常是較低的版本,所以以下所作的介紹,都將基於較低的版本0.9.4。
opcontrol --version
opcontrol: oprofile 0.9.4 compiled on Nov 22 2011 12:03:03
個人生產環境是RHEL 5.4,若是須要oprofile內核,則須要安裝內核符號信息,命令以下:
rpm -i kernel-debuginfo-common-2.6.18-164.el5.x86_64.rpm
rpm -i kernel-debuginfo-2.6.18-164.el5.x86_64.rpm
安裝好的vmlinux在這裏/usr/lib/debug/lib/modules/2.6.18-164.el5/vmlinux
oprofile包含有一系列的工具集,這些工具默認在路徑/usr/bin之下,工具及說明分別以下:
1)op_help:列出可用的事件,並帶有簡短的描述。
2)opcontrol:控制oprofile的數據收集。
2012年,oprofile 0.9.8開始引入operf工具,將替換舊的基於opcontrol的工具,容許非root用戶也能夠進行性能監測。
opcontrol的配置默認在/root/.oprofile/daemonrc下,能夠使用demsg查看oprofile使用的是哪種模式。
3)opreport:對結果進行統計輸出。通常存在兩種基本形式。
opreport -f
opreport -l ` which oprofiled` 2 > /dev/null | more
4)opannaotate:產生帶註釋的源文件/彙編文件,源語言級的註釋須要在編譯源文件時加上的調試符號信息的支持。
5)opgprof:產生與gprof類似的結果。
6)oparchive:將全部的原始數據文件收集打包,從而能夠在另外一臺機器上進行分析。
7)opimport:將採樣的數據庫文件從另外一種abi外部格式轉化爲本地格式。
基本步驟具體以下:
1)opcontrol --no-vmlinux #不對內核進行性能分析 或者opcontrol --vmlinux=/boot/vmlinux-`uname-r`#對內核進行性能分析
默認的配置存放在/root/.oprofile/daemonrc中
默認的採樣的文件存放在/var/lib/oprofile/samples/中
也能夠指定默認數據存放的地方,命令以下:
opcontrol --no-vmlinux --session-dir=/home/me/tmpsession
opcontrol --start --session-dir=/home/me/tmpsession
在開始收集採樣數據前可回顧下咱們的設置,運行opcontrol --status。
2)清除上一次採樣到的數據。 opcontrol --reset
3)開始收集信息。opcontrol --start
4)運行程序,施加負荷。
5)dump出收集的數據,而後能夠繼續運行或關閉oprofile。 opcontrol --dump
咱們能夠隨時運行命令opcontrol --reset清除咱們當前會話的採樣數據,重置計數器。
6)中止數據收集,且kill掉daemon進程。 opcontrol --shutdown
默認將數據放在/var/lib/oprofile/samples下,能夠使用opcontrol--reset清理文件。
7)輸出統計報告。 opreport -f [--session-dir=dir]
查看系統級別的報告:opreport --long-filenames。
查看模塊級別的報告,opreport image:進程路徑-l,命令以下。
opreport -l image:/bin/myprog,/bin/myprog2
opreport image:/usr/bin/\*
查看源碼級別的報告,opannotate image:進程路徑-s。 輸出的報告相似於圖16-12的形式。
其中,第一列是收集的採樣數據的統計次數,第二列是耗費的時間百分比,第三列是進程名。
oprofile還能夠觀測事件列表命令以下。 opcontrol --list-events
以下是一個完整的示例。
opcontrol --start --no-vmlinux --separate=kernel #啓動收集 程序運行中,此時 oprofile收集數據
opcontrol --status #顯示狀態
opcontrol -h #關閉 oprofile
opreport -f | more #顯示報告
opreport image: /usr/local/mysql-5.1.58-linux-x86_64-glibc23/bin/mysqld
opreport -l image: /usr/local/mysql-5.1.58-linux-x86_64-glibc23/bin/mysqld | more
注意事項 :
不建議在虛擬機裏利用oprofile來測試性能。
調試的內核最好是原生內核。
使用oprofile定位CPU密集型的場景是合適的,但對於某些I/O密集型或是低負載類型的場景就會有些無能爲力,這時能夠藉助其餘工具進一步定位性能瓶頸。
5.free
free命令用於顯示系統的自由內存和已經被使用的內存。
free指令顯示的內存的使用狀況包括實體內存、虛擬的交換文件內存、共享內存區段及系統核心使用的緩衝區等。
語法:free [-bkmotV] [-s]
參數及說明分別以下:
-b:以Byte爲單位顯示內存使用狀況。
-k:以KB爲單位顯示內存使用狀況。
-m:以MB爲單位顯示內存使用狀況。
-o:不顯示緩衝區調節列。
-s:持續觀察內存使用情況。
-t:顯示內存總和列。
-V:顯示版本信息。
以下是free命令的輸出:
total used free shared buffers cached
Mem: 65966584 65787112 179472 0 443532 15532932
-/+ buffers/cache: 49810648 16155936
Swap: 16779884 316 16779568
[root@bogon sa]# free
total used free shared buff/cache available
Mem: 8057824 357596 7198732 17448 501496 7601420
Swap: 4063228 0 4063228
其中各項說明以下:
Mem:表示物理內存統計。
-/+buffers/cache:表示物理內存的緩存統計。
Swap:表示硬盤上交換分區的使用狀況,這裏咱們不去關心。
系統的總物理內存:65966584(64GB),但系統當前真正可用的內存大小並非第一行free標記的179472KB,它僅表明未被分配的內存。
如下咱們將逐行解釋輸出:
第1行 Mem
total:表示物理內存總量。 total=used+free
used:表示總計分配給緩存(包含buffers與cache)使用的數量,但其中可能有部分緩存並未實際使用。
free:未被分配的內存。
shared:共享內存。
buffers:系統已分配但未被使用的buffers數量。
cached:系統已分配但未被使用的cache數量。
buffer指的是做爲buffer cache的內存,即塊設備的讀寫緩衝區。
cache指的是做爲page cache的內存,即文件系統的cache。
若是cache的值很大,則說明cache住的文件數不少。若是頻繁訪問到的文件都能被cache住,那麼磁盤的讀I/O一定會很是小。
可是過大的文件cache可能會影響到內存的使用效率,致使操做系統上其餘進程的內存不夠大,甚至還會使用到swap空間。
第2行 -/+buffers/cache
used:也就是第一行中的used-buffers-cached,也是實際使用的內存總量。
free:未被使用的buffers與cache和未被分配的內存之和(見第一行buffers、cached、free),這就是系統當前實際可用的內存。
第2行所指的是從應用程序的角度來看,對應用程序來說,buffers/cache是等同可用的,當程序使用內存時,buffers/cache會很快地被使用。
從應用程序的角度來講,可用內存=系統free memory+buffers+cached。
第1行Mem是對操做系統來說的。buffers/cache都是屬於被使用的,因此它認爲free只有179472。
咱們通常理解的free輸出應該從應用程序的角度去理解,應該關注第二行的free輸出,也就是16155936KB。由於那些buffers和cache是可能被重用的。
6.top
可以實時顯示系統中各個進程的資源佔用情況,相似於Windows的任務管理器。它不斷更新最新狀況直至用戶結束程序。
默認狀況下,可列出消耗CPU資源最多的十多個進程。
你也能夠交互式地鍵入不一樣的鍵按其餘選項進行排序,好比
按【M】鍵可列出佔用最多內存的幾個進程,
按【1】鍵可切換顯示各CPU的使用率或總體使用率等,
按【K】鍵可終止某個進程,
按空格鍵可從新刷新屏幕輸出。
如下是一個系統運行top命令的例子。
top - 17:10:08 up 497 days, 40 min, 1 user, load average: 0.19, 0.26, 0.26
Tasks: 433 total, 2 running, 430 sleeping, 0 stopped, 1 zombie
Cpu(s): 0.5%us, 0.2%sy, 0.0%ni, 99.1%id, 0.2%wa, 0.0%hi, 0.1%si, 0.0%st
Mem: 65966584k total, 65791212k used, 175372k free, 444868k buffers
Swap: 16779884k total, 316k used, 16779568k free, 15532032k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
19462 mysql 15 0 29.4g 29g 9996 S 16.2 46.4 111787:00 /usr/local/mysql/bin/mysqld --defaults-file=/my.cnf
24901 nemo 15 0 13024 1368 812 R 0.3 0.0 0:00.16 top -c
1 root 15 0 10368 640 544 S 0.0 0.0 5:12.51 init [3]
2 root RT -5 0 0 0 S 0.0 0.0 1:39.38 [migration/0]
3 root 34 19 0 0 0 S 0.0 0.0 50:46.99 [ksoftirqd/0]
4 root RT -5 0 0 0 S 0.0 0.0 0:00.02 [watchdog/0]
第一列顯示的是當前時間、系統運行時間(up time)、使用者(users)數目和平均負載(load average)。
能夠按 l 鍵切換是否顯示。
top - 17:10:08 up 497 days, 40 min, 1 user, load average: 0.19, 0.26, 0.26
平均負載的三個數值分別表示在平均過去1分鐘、5分鐘和15分鐘,可運行或不可中斷狀態的進程數目。
平均負載爲1.0表示一個CPU被佔用全部時間。若是計算 機有多個CPU,則平均負載的參考值亦會成倍數增加。
例如一個雙CPU 4核的計算機,全部CPU全部時間被徹底佔用時的平均負載應該爲1.0×2×4=8.0。
第二列顯示任務(task)信息,任務表示一個進程或一個多線程進程中的某個線程,
任務信息包括任務總數、運行中(running)、睡眠中(sleeping)、已中止 (stopped)和不能運行(zombie)的進程數目,zombie就是殭屍進程。
能夠按【t】鍵切換和下一列CPU狀態列是否一同顯示。
Tasks: 433 total, 2 running, 430 sleeping, 0 stopped, 1 zombie
第三列顯示CPU狀態,包括如下信息。
us(user):用戶空間(user space)佔用CPU的百分比。
sy(system):核心空間(kernelspace)佔用CPU的百分比。
ni(nice):nice值比通常值0大(優先序較低)的進程佔用CPU的百分比。
id(idle):CPU空閒時間百分比。
wa(iowait):CPU等待的百分比。當值太高時(如超過30%),表示系統的存儲或網絡I/O性能存在問題。
hi(H/W Interrupt):CPU處理硬件中斷時間的百分比。除非光驅不斷檢查是否有光盤外,此值通常不會過高。
si(S/W Interrupt):CPU處理軟件中斷時間的百分比,此值通常不會過高。
st(Steal):在如Xen等的虛擬環境下,CPU運做虛擬機器時間的百分比。過高,則表示可能須要中止一些虛擬機器。
Cpu(s): 0.5%us, 0.2%sy, 0.0%ni, 99.1%id, 0.2%wa, 0.0%hi, 0.1%si, 0.0%st
第四列和第五列分別顯示內存和交換空間(swap space)的使用率。
能夠按【M】鍵切換是否顯示。
Mem: 65966584k total, 65791212k used, 175372k free, 444868k buffers
Swap: 16779884k total, 316k used, 16779568k free, 15532032k cached
其餘一些示例以下。
默認狀況下,top是交互式(interactive)的輸出,會一直在屏幕上刷新,若是咱們須要獲取top的輸出,那麼咱們能夠使用批處理模式。
例如以下示例。
top -b -d 5 -n 5
其中各參數及說明分別以下。
-b:批處理模式操做。
-d:刷新時間間隔。
-n:交互次數,即輸出幾回。
以下例子可指定某個或某幾個進程的top輸出:top -p 4360,4358
以下例子可指定某個用戶的top輸出:top -u garychen
7.dstat
對比其餘工具,dstat更強大,可觀察性也更強,dstat可綜合顯示各類系統資源的使用狀況,如磁盤、網絡、CPU、內存等。
如下是運行dstat的一個示例。
dstat 2 10
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
4 0 95 0 0 0|2269B 641k| 0 0 | 0 0 |2867 5261
12 0 87 0 0 0| 0 134k| 552k 3655k| 0 0 |6787 11k
19 0 80 0 0 0| 0 1096k| 608k 3724k| 0 0 |6924 12k
6 0 94 0 0 0| 0 1182k| 501k 3246k| 0 0 |6351 8553
15 1 84 0 0 0| 0 206k| 576k 4241k| 0 0 |6800 12k
21 1 78 0 0 0| 0 504k| 597k 6403k| 0 0 |7053 14k
12 0 87 0 0 0| 0 304k| 461k 5518k| 0 0 |6229 9607
18 1 81 0 0 0| 0 328k| 511k 6113k| 0 0 |6651 12k
16 1 83 0 0 0| 0 266k| 580k 6359k| 0 0 |7116 14k
16 0 83 0 0 0| 0 188k| 673k 7052k| 0 0 |7452 11k
14 0 86 0 0 0| 0 144k| 532k 6051k| 0 0 |6557 8724
[root@bogon sa]# dstat 2 10
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
0 0 100 0 0 0| 264B 301B| 0 0 | 0 0 | 92 142
0 0 100 0 0 0| 0 0 | 858B 490B| 0 0 | 98 142
0 0 100 0 0 0| 0 0 |2085B 511B| 0 0 | 179 212
0 0 100 0 0 0| 0 0 | 806B 186B| 0 0 | 131 186
0 0 100 0 0 0| 0 0 |1080B 338B| 0 0 | 102 147
0 0 100 0 0 0| 0 0 |1436B 338B| 0 0 | 129 171
0 0 100 0 0 0| 0 0 |1807B 338B| 0 0 | 131 169
0 0 100 0 0 0| 0 0 |1856B 338B| 0 0 | 139 176
0 0 100 0 0 0| 0 0 |1343B 338B| 0 0 | 116 156
0 0 100 0 0 0| 0 0 | 952B 338B| 0 0 | 96 144
0 0 100 0 0 0| 0 0 |1364B 338B| 0 0 | 112 147
上面輸出中total-cpu-usage部分的hiq、siq分別爲硬中斷和軟中斷的次數。
上面輸出中system部分的int、csw分別爲系統的中斷(interrupt)次數和上下文切換(context switch)。
若要將結果輸出到CSV文件能夠加--output filename。
咱們能夠使用繪圖工具對此文件進行畫圖。
若是內核支持,還能夠使用--top-io-adv參數查看最消耗I/O的進程。
[root@bogon sa]# dstat --help
Usage: dstat [-afv] [options..] [delay [count]]
Versatile tool for generating system resource statistics
Dstat options:
-c, --cpu enable cpu stats
-C 0,3,total include cpu0, cpu3 and total
-d, --disk enable disk stats
-D total,hda include hda and total
-g, --page enable page stats
-i, --int enable interrupt stats
-I 5,eth2 include int5 and interrupt used by eth2
-l, --load enable load stats
-m, --mem enable memory stats
-n, --net enable network stats
-N eth1,total include eth1 and total
-p, --proc enable process stats
-r, --io enable io stats (I/O requests completed)
-s, --swap enable swap stats
-S swap1,total include swap1 and total
-t, --time enable time/date output
-T, --epoch enable time counter (seconds since epoch)
-y, --sys enable system stats
--aio enable aio stats
--fs, --filesystem enable fs stats
--ipc enable ipc stats
--lock enable lock stats
--raw enable raw stats
--socket enable socket stats
--tcp enable tcp stats
--udp enable udp stats
--unix enable unix stats
--vm enable vm stats
--plugin-name enable plugins by plugin name (see manual)
--list list all available plugins
-a, --all equals -cdngy (default)
-f, --full automatically expand -C, -D, -I, -N and -S lists
-v, --vmstat equals -pmgdsc -D total
--bits force bits for values expressed in bytes
--float force float values on screen
--integer force integer values on screen
--bw, --blackonwhite change colors for white background terminal
--nocolor disable colors (implies --noupdate)
--noheaders disable repetitive headers
--noupdate disable intermediate updates
--output file write CSV output to file
--profile show profiling statistics when exiting dstat
delay is the delay in seconds between each update (default: 1)
count is the number of updates to display before exiting (default: unlimited)
8.netstat
netstat命令用於顯示各類網絡相關的信息。
常見的參數及說明分別以下:
-a:all,顯示全部選項,默認不顯示LISTEN相關。
-t:tcp,僅顯示TCP相關選項。
-u:udp,僅顯示UDP相關選項。
-n:不顯示別名,能顯示爲數字的所有轉化成數字。
-l:僅列出有正在Listen(監聽)的服務狀態。
-p:顯示創建相關連接的程序名。
-r:顯示路由信息,路由表。
-e:顯示擴展信息,例如uid等。
-s:按各個協議進行統計。
-c:每隔一個固定時間,執行該netstat命令。
下面將列舉幾個示例進行說明。
咱們能夠使用netstat -tlpn顯示當前正在監聽TCP協議端口的MySQL服務。
如下命令將每隔一秒輸出一次網絡信息,檢測MySQL服務是否已經起來並監聽端口了。
netstat -tlpnc |grep mysql
如下命令將查看鏈接到MySQL服務端口的IP信息,並按鏈接數進行排序。
netstat -nat | grep ":3306" |awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -20
[root@bogon sa]# netstat --help
usage: netstat [-vWeenNcCF] [<Af>] -r netstat {-V|--version|-h|--help}
netstat [-vWnNcaeol] [<Socket> ...]
netstat { [-vWeenNac] -I[<Iface>] | [-veenNac] -i | [-cnNe] -M | -s [-6tuw] } [delay]
-r, --route display routing table
-I, --interfaces=<Iface> display interface table for <Iface>
-i, --interfaces display interface table
-g, --groups display multicast group memberships
-s, --statistics display networking statistics (like SNMP)
-M, --masquerade display masqueraded connections
-v, --verbose be verbose
-W, --wide don't truncate IP addresses
-n, --numeric don't resolve names
--numeric-hosts don't resolve host names
--numeric-ports don't resolve port names
--numeric-users don't resolve user names
-N, --symbolic resolve hardware names
-e, --extend display other/more information
-p, --programs display PID/Program name for sockets
-o, --timers display timers
-c, --continuous continuous listing
-l, --listening display listening server sockets
-a, --all display all sockets (default: connected)
-F, --fib display Forwarding Information Base (default)
-C, --cache display routing cache instead of FIB
-Z, --context display SELinux security context for sockets
<Socket>={-t|--tcp} {-u|--udp} {-U|--udplite} {-S|--sctp} {-w|--raw}
{-x|--unix} --ax25 --ipx --netrom
<AF>=Use '-6|-4' or '-A <af>' or '--<af>'; default: inet
List of possible address families (which support routing):
inet (DARPA Internet) inet6 (IPv6) ax25 (AMPR AX.25)
netrom (AMPR NET/ROM) ipx (Novell IPX) ddp (Appletalk DDP)
x25 (CCITT X.25)
9.mtr
mtr是一個功能強大的網絡診斷工具,綜合了ping和tracerotue的功能。它能夠幫助系統管理員診斷網絡異常,並提供友好的網絡狀態報告以供分析。
如下將介紹mtr的數據是如何產生的,如何解讀mtr的報告,以及如何診斷異常。
mtr使用「ICMP」包來測試網絡爭用和傳輸,mtr的工做原理是:啓動mtr時,它經過發送不斷增加TTL(生存時間)的ICMP包來測試本機和目標主機的連通性。
TTL 控制了ICMP包要通過多少「跳」纔會被返回,
例如,主叫方首先發出TTL=1的ICMP數據包,第一個路由器將TTL減1得0後就再也不繼續轉發此數據包,
而是返回一個 ICMP超時報文,主叫方從超時報文中便可提取出數據包所通過的第一個網關地址。
而後又發出一個TTL=2的ICMP數據包,可得到第二個網關地址,依次遞增TTL便獲取了沿途全部網關的地址。
mtr連續發送不斷增加TTL(生存時間)的ICMP包以收集中間路由器的信息,包括各類鏈接、響應能力、狀態等信息,
這就容許mtr可以打印出中間路由器的響應率和響應時間直到目標主機。
丟包率或響應時間的忽然上升可能意味着這個網絡存在問題。
咱們能夠把mtr看做一個單向的衡量網絡質量的工具,從本機到目的主機和從目的主機到本機每每走的是不同的網絡路徑,
本機到目的主機沒有丟包,但目的主機到本機卻可能會丟包。
從本地不一樣的主機到目的主機也可能走不同的網絡路徑。
因此,若是診斷出是網絡問題,那麼建議在兩個方向上都使用mtr進行測試驗證,若是能夠,多驗證一些主機之間的通訊。
示例以下:mtr --report www.baidu.com
添加--report表示發送10個包到目的主機www.baidu.com,而後生成報告。
若是不加--report選項,那麼mtr會一直在交互模式中運行,交互模式會不斷刷新報告以反映最新的信息。
通常狀況下,--report選項生成的報告就已經足夠了。
如何閱讀報告。 以下是一個對baidu的mtr報告。
[root@bogon sa]# mtr --report www.baidu.com
Start: Tue Dec 17 20:51:31 2019
HOST: bogon Loss% Snt Last Avg Best Wrst StDev
1.|-- bogon 0.0% 10 0.2 0.3 0.2 0.7 0.0
2.|-- 1.202.223.97 0.0% 10 1.9 41.7 1.9 103.7 40.5
3.|-- ??? 100.0 10 0.0 0.0 0.0 0.0 0.0
4.|-- 220.181.0.234 70.0% 10 1.8 7.2 1.8 17.4 8.9
5.|-- 220.181.16.62 20.0% 10 3.6 3.7 2.9 5.7 0.7
6.|-- 220.181.182.26 0.0% 10 2.2 2.8 2.0 6.9 1.4
7.|-- ??? 100.0 10 0.0 0.0 0.0 0.0 0.0
8.|-- ??? 100.0 10 0.0 0.0 0.0 0.0 0.0
9.|-- ??? 100.0 10 0.0 0.0 0.0 0.0 0.0
10.|-- 220.181.38.150 0.0% 10 1.9 2.0 1.9 2.2 0.0
如上的mtr通過了10跳(hops),通常咱們使用術語「跳」的計數來標識報告中的問題,「跳」指的是因特網上網絡包到達目的地所通過的節點和路由器。
輸出項說明以下:
loss%:每一跳的丟包率。
Snt:發送的數據包數量。
Last:最後一個包的響應時間(毫秒)。
Avg:全部包的平均響應時間(毫秒),通常狀況下,咱們更關注這個響應時間。
Best:最短的響應時間(毫秒)。
Wrst:最長的響應時間(毫秒)。
StDev:響應時間的標準差。StDev越大,表示各個包的響應時間差別越大。
若是差別很大,咱們可能須要審視下Avg的平均值是否可靠,看看Best和Wrst,確認 Avg是否可以表明真實的延時時間,是否有被其餘的因素所幹擾。
通常狀況下,咱們能夠把以上的輸出報告分解爲三個部分,前幾跳每每是本地ISP,最後的兩三跳每每是目的主機的ISP,中間的一些跳是網絡傳輸通過的一些路由器。
對於本地ISP和目的主機ISP的網絡問題,咱們每每能夠及時反饋,獲得處理,但對於一些中間結點的路由器出現的問題,每每ISP自身也無力去解決。
下面咱們經過4個例子來講明如何分析報告。
示例1: 當咱們閱讀報告時,咱們通常關注的是丟包率和延時。
若是咱們在任何一跳看到有超過必定百分比的延時(好比,超過5%),那麼那個路由器就可能存在問題,
但也存在這樣一種狀況,一些ISP限制了ICMP包,咱們看到了很高的丟包率,但實際上並無發生丟包,
咱們看到第2跳的丟包率高達50%,但實際上並無丟包。
判斷是否真正丟包,能夠看下後續的跳,若是後續的跳顯示沒有丟包,那麼就沒有丟包,而是由於ISP限制了ICMP的速率。
示例2: ICMP速率限制和丟包可能會同時出現,這個時候,丟包率應該選擇後續的跳中最低的丟包率,這個最低的丟包率才表明實際的丟包率。
示例3: 有時目的主機的不正確配置也會致使丟包,好比目的主機有防火牆Drop掉了ICMP包,咱們能夠看到最後一跳是100%的丟包率。
示例4: 有時路由器出於某種緣由沒有正確配置,或者是對其有特殊設置,例以下面的例子中,咱們可能會看到許多問號,但網絡質量良好,並無發生丟包。
注意事項:
跨IDC的網絡,自己就不是很穩定,特別是超長距離的橫跨太平洋、大西洋的網絡,中間通過的節點不少,極可能會出現波動或堵塞,致使延時很高,
若是網絡丟包率不是很高(好比大於10%),那麼你不須要過度地關注,
從架構上進行設計,讓用戶儘量地訪問本地的網絡,提升用戶體驗,比去解決跨IDC的高延時和不穩定的網絡會更具實踐性。
網絡的質量也和本地的鏈接、負載有關係,因此測量的時候也要留意這些因素的影響。
10.strace
strace是一個簡單易用的工具,用於跟蹤一個進程的系統調用或信號產生的狀況,它最簡單的用法就是跟蹤一個可執行文件的執行,記錄程序運行過程當中的系統調用。
經過使用參數-c,它還能對進程中全部的系統調用作一個統計分析。它也能篩選出特定的系統調用,如下是一些示例。
1)查找程序啓動的時候加載了哪些配置文件。
$ strace php 2>&1 | grep php.ini 能夠查看加載了哪一個 php.ini文件。
若是想只篩選某個系統調用則能夠使用以下命令。 $ strace -e open php 2>&1 | grep php.ini
2)有時程序沒有權限打開文件,它並不會提示你詳細的信息,這時咱們就能夠用strace來判斷是否存在權限的問題。
$ strace -e open,access 2>&1 | grep your-filename
3)對於一些很消耗資源的進程,咱們有時會想知道它們正在作什麼?知道了pid後,能夠使用-p參數來查看。 $ strace -p 1344
4)加-c參數進行統計分析,能夠查看哪些操做佔據了最多資源。
$ strace -c -p 1344 監視一段時間後,按【Ctrl+C】鍵退出,會輸出統計報表供你分析。
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
96.49 0.014377 55 261 37 futex
1.30 0.000194 13 15 epoll_pwait
1.13 0.000169 15 11 write
0.79 0.000117 39 3 pselect6
0.15 0.000023 4 6 3 read
0.13 0.000020 20 1 1 restart_syscall
------ ----------- ----------- --------- --------- ----------------
100.00 0.014900 297 41 total
[root@bogon sa]# strace -h
usage: strace [-CdffhiqrtttTvVwxxy] [-I n] [-e expr]...
[-a column] [-o file] [-s strsize] [-P path]...
-p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]
or: strace -c[dfw] [-I n] [-e expr]... [-O overhead] [-S sortby]
-p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]
Output format:
-a column alignment COLUMN for printing syscall results (default 40)
-i print instruction pointer at time of syscall
-o file send trace output to FILE instead of stderr
-q suppress messages about attaching, detaching, etc.
-r print relative timestamp
-s strsize limit length of print strings to STRSIZE chars (default 32)
-t print absolute timestamp
-tt print absolute timestamp with usecs
-T print time spent in each syscall
-x print non-ascii strings in hex
-xx print all strings in hex
-y print paths associated with file descriptor arguments
-yy print protocol specific information associated with socket file descriptors
Statistics:
-c count time, calls, and errors for each syscall and report summary
-C like -c but also print regular output
-O overhead set overhead for tracing syscalls to OVERHEAD usecs
-S sortby sort syscall counts by: time, calls, name, nothing (default time)
-w summarise syscall latency (default is system time)
Filtering:
-e expr a qualifying expression: option=[!]all or option=[!]val1[,val2]...
options: trace, abbrev, verbose, raw, signal, read, write
-P path trace accesses to path
Tracing:
-b execve detach on execve syscall
-D run tracer process as a detached grandchild, not as parent
-f follow forks
-ff follow forks with output into separate files
-I interruptible
1: no signals are blocked
2: fatal signals are blocked while decoding syscall (default)
3: fatal signals are always blocked (default if '-o FILE PROG')
4: fatal signals and SIGTSTP (^Z) are always blocked
(useful to make 'strace -o FILE PROG' not stop on ^Z)
Startup:
-E var remove var from the environment for command
-E var=val put var=val in the environment for command
-p pid trace process with process id PID, may be repeated
-u username run command as username handling setuid and/or setgid
Miscellaneous:
-d enable debug output to stderr
-v verbose mode: print unabbreviated argv, stat, termios, etc. args
-h print help message
-V print version
16.2.2 MySQL診斷工具
1.MySQL自帶工具
MySQL自帶了一些工具,大都是爲管理的目的而發佈的一些工具,如mysql、mysqladmin、mysqldump,具體的使用方法,請參考前面的章節。
若是咱們須要得到更全面的信息,進行更準確的診斷,那麼更好的選擇是使用一些第三方工具,如Percona工具包。
通常咱們能夠經過以下幾種方式來收集信息。
經過使用mysql、mysqladmin執行一些查詢和命令來獲取當前的全局狀態變量。
查詢information_schema庫下面的表,information_schema庫保存了一些數據庫的元信息,如鏈接信息。
MySQL 5.5版本後新增了performance_schema庫,這個庫下的動態性能視圖主要用於收集MySQL的性能信息,好比鎖、事件等信息。
基於事件的調優是一個方向,將來performance_schema會愈來愈成熟,將成爲很重要的調優手段。
2.Percona工具包詳解
(1)介紹和安裝
Percona工具包是Percona公司的一個性能診斷工具集,因爲MySQL自帶的性能診斷工具很匱乏,因此不少時候須要藉助第三方的工具來協助診斷和定位問題,
做 爲一名DBA,有必要熟練使用Percona工具包裏的部分工具,以便更有效地管理數據庫和診斷問題。
如下將簡要介紹Percona的安裝方式和一些經常使用的工具。
本書所介紹的內容是基於Percona tool kit 2.1的版本。因爲開源工具發展得比較快,可能這本書中所舉的例子已再也不適用。
因爲是第三方工具,雖然有Percona公司的支持,許多工具也通過了大量用戶的驗證,可是仍然可能存在一些風險因素。
強烈建議在使用如下所介紹的工具之 前,仔細閱讀官方文檔,並通過本身的測試,驗證其確實是可行的,才投入到生產環境中使用。
咱們能夠下載源碼包、二進制包或RPM包進行安裝。
你須要確保Perl已經安裝了模塊DBI和DBD::mysql。能夠很容易地下載到單獨的工具,下載命令以下。
wget percona.com/get/TOOL(工具名 )
如下以RHEL 5.4 64位爲例簡要說明如何安裝Percona工具。
1) root下
[root@db1000 pkgs]# perl --version
his is perl, v5.8.8 built for x86_64-linux-thread-multi
cpan> install Time::HiRes
2) 確認 perl已經安裝了 DBI,DBD::mysql, Time::HiRes
3) 安裝
percona-toolkit下載源碼包,解壓之,進入解壓縮目錄
perl Makefile.PL
make
make test
make install 默認安裝在 /usr/bin/ 下
ls -lrt /usr/bin/pt-*
Percona工具也有其配置文件,配置文件的語法簡單直接,配置文件的規則具體以下。
每行的格式能夠是:option=value或option,等於號兩邊的空格被忽略。
--表示選項解析結束,後面的行都是程序的附加參數。
忽略空行。
空格#‘空格’+‘#’表示後面的是註釋內容。
Percona工具讀取配置文件的順序具體以下。
1)/etc/percona-toolkit/percona-toolkit.conf:全局配置。
2)/etc/percona-toolkit/TOOL.conf:能夠指定某個工具的具體配置,TOOL是工具名,如pt-query-digest
3)$HOME/.percona-toolkit.conf:這是用戶下的一個全局配置。
4)$HOME/.TOOL.conf:這是用戶下的某個工具的具體配置。
也能夠在命令行中指定配置文件,如--config/path/to/file,注意不要有=號,必須把--config參數放在命令行的最前面。--config表示不讀取任何配置文件。
Percona工具包通常支持使用DSN語法來設置如何去鏈接MySQL。
DSN的英文全稱是DATA SOURCE NAME,一個DSN是一個逗號分隔的key=value形式的字符串,例如:h=host1,P=3306,u=bob。
DSN對於大小寫敏感,中間不容許有空格,若是有空格的話,必需要用引號引發來。
也有部分工具不支持DSN的方式鏈接數據庫,它們自身提供了鏈接數據庫的參數,如:「--host」、「--user」、「--password」。
一些工具可同時使用DSN和「--host」、「--user」、「--password」之類的參數。
一些標準的key及其說明分別以下:
A:字符集。 例如,A=utf8表示在鏈接時SET NAMES UTF8
D:數據庫名。
F:設置mysql客戶端庫讀取的配置文件,若是不進行設置,那麼就讀取標準配置文件,如/etc/my.cnf、$HOME/.my.cnf。
h:主機名或IP。
p:密碼。
P:端口。
S:socket file。
u:數據庫帳號。
有些工具還會附加一些其餘的key,這裏就不贅述了。
能夠經過設置環境變量PTDEBUG=1,啓用Percona工具的Debug功能。命令的Debug信息會輸出到STDERR,
例如,輸出Debug信息到一個文件,命令以下: PTDEBUG=1 pt-table-checksum ... > FILE 2>&1
(2)pt-query-digest
pt-query-digest是最應該被掌握的一個工具。它能夠分析MySQL的各類日誌,如慢查詢日誌、generel日誌,也能夠分析SHOW PROCESSLIST的輸出。
配合tcpdump 咱們還能夠對線上數據庫流量進行採樣,實時監控數據庫流量,及時發現性能問題。
其基本用法以下:pt-query-digest /path/to/slow.log > /path/to/keep/report_file
若是你有大量的數據庫節點,能夠考慮把pt-query-digest的分析報告寫入數據庫,以方便檢索和繪圖。
輸出的結果報表相似以下,如下截取了報告的部份內容。
# Overall: 565 total, 22 unique, 0.00 QPS, 0.00x concurrency _____________
# Time range: 2012-09-22 18:33:43 to 2012-10-16 10:45:31
# Attribute total min max avg 95% stddev median
# ============ ======= ======= ======= ======= ======= ======= =======
# Exec time 1233s 503ms 15s 2s 7s 2s 1s
# Lock time 53ms 31us 145us 94us 119us 17us 93us
# Rows sent 1.67k 0 20 3.02 9.83 4.12 0.99
# Rows examine 616.77M 72.90k 12.03M 1.09M 6.61M 2.02M 245.21k
# Query size 139.49k 25 381 252.81 346.17 70.94 234.30
# Profile
# Rank Query ID Response time Calls R/Call Apdx V/M Item
# ==== ================= ============= ==== ========== ==== ====== ========
# 1 0xBE5D289C750F172A 308.6929 25.0% 40 7.7173 0.00 0.08 SELECT ccc tbl_eee tbl_ddd bbb
# 2 0x5C898C5E065DD204 149.4144 12.1% 105 1.4230 0.50 0.00 SELECT tbl_ddd_info tbl_eee tbl_ddd
# 3 0x6F05415421300718 136.7381 11.1% 97 1.4097 0.50 0.00 SELECT tbl_ddd_info tbl_eee tbl_ddd
# 4 0x2E9AE41A4D2149A1 123.0681 10.0% 22 5.5940 0.00 0.02 SELECT ccc tbl_eee tbl_ddd bbb
# 5 0xAFF556BC27138443 121.9603 9.9% 73 1.6707 0.50 0.00 SELECT tbl_ddd_info tbl_eee tbl_ddd
# 6 0xD07F224EF598BD9A 105.0456 8.5% 16 6.5653 0.00 0.23 SELECT ccc tbl_eee tbl_ddd bbb
# 7 0xC22F9709F846BB4E 99.1936 8.0% 73 1.3588 0.50 0.00 SELECT tbl_ddd_info tbl_eee tbl_ddd
# 8 0x4CAD792BF4A54CE9 53.7477 4.4% 4 13.4369 0.00 0.17 SELECT tbl_fff tbl_eee tbl_ddd
# 9 0x347319A37AC29893 39.1390 3.2% 69 0.5672 1.00 0.00 SELECT tbl_fff pt_game_base_score
# 10 0x7EF77B274F1C37D3 27.2826 2.2% 4 6.8207 0.00 0.00 SELECT ccc tbl_eee tbl_ddd bbb
# 11 0x8383B2CB219358F3 16.7553 1.4% 18 0.9308 0.97 0.00 SELECT tbl_iii tbl_hhh tbl_eee
# MISC 0xMISC 51.5793 4.2% 44 1.1723 NS 0.0 <11 ITEMS>
# Query 1: 0.00 QPS, 0.00x concurrency, ID 0xBE5D289C750F172A at byte 120071
# This item is included in the report because it matches --limit.
# Scores: Apdex = 0.00 [1.0]*, V/M = 0.08
# Query_time sparkline: | ^_|
# Time range: 2012-09-25 11:01:09 to 2012-10-16 10:14:31
# Attribute pct total min max avg 95% stddev median
# ============== ======= ======= ====== ====== ====== ======= ======
# Count 7 40
# Exec time 25 309s 7s 10s 8s 9s 802ms 7s
# Lock time 6 4ms 59us 110us 89us 103us 12us 91us
# Rows sent 2 40 1 1 1 1 0 1
# Rows examine 45 281.88M 6.73M 7.29M 7.05M 6.94M 183.33k 6.94M
# Query size 5 7.19k 184 184 184 184 0 184
# String:
# Hosts
# Users db_user
# Query_time distribution
# 1us # 10us # 100us # 1ms # 10ms # 100ms # 1s
################################################################
# 10s+ #
# Tables
# SHOW TABLE STATUS LIKE 'ccc'\G
# SHOW CREATE TABLE `tbl_eee`\G
# SHOW TABLE STATUS LIKE 'tbl_ddd'\G
# SHOW CREATE TABLE `bbb`\G
# SHOW TABLE STATUS LIKE 'ggg'\G
# EXPLAIN /*!50100 PARTITIONS*/
select ... from ....
輸出格式的解釋具體以下:
Rank:全部查詢日誌分析完畢後,此查詢的排序。
Query ID:查詢的標識字符串。能夠搜索這個字符串以快速定位到慢查詢語句。
Responsetime:總的響應時間,以及總佔比,應優化佔比較高的查詢,對於比例較小的查詢通常能夠忽略,不進行優化。
Calls:查詢被調用執行的次數。
R/Call:每次執行的平均響應時間。
Apdx:應用程序的性能指數得分,響應時間越長,得分越低。
V/M:響應時間的方差均值比。可說明樣本的分散程度,這個值越大,每每是越值得考慮優化的對象。
Item:查詢的簡單顯示,包含了查詢涉及的表。
對於報告中的以下輸出,咱們能夠利用偏移量到慢查詢日誌裏定位具體的sql語句。
# Query 1: 0.00 QPS, 0.00x concurrency, ID 0xBE5D289C750F172A at byte 120071
定位方法以下:tail -c +120071 /path/to/slow.log. | head
查詢響應時間的分佈,這裏使用了很形象的表示方式,以下所示。
# Query_time distribution # 1us # 10us # 100us # 1ms # 10ms# 100ms # 1s # 10s+ #
能夠看到,有許多查詢響應時間在1秒到10秒之間。
對於一些TOP SQL,咱們能夠使用EXPLAIN工具分析執行計劃,進行調優。
對於更新語句,此工具會幫你改寫成能夠使用EXPLAIN工具的SELECT語句。
其餘的一些使用方式示例以下。
1)分析SHOW PROCESSLIST的輸出。
./pt-query-digest --processlist S=/path/3307/mysql.sock,u=root,p=dxwd\* --interval 5 --run-time 5m
pt-query-digest --processlist h=host1 --print --no-report
2)分析tcpdump的輸出。
分析執行SQL的頻率,通常在高峯期取樣,必定要記得關閉tcpdump,由於生成的文件可能會很大。
首先運行命令。 nohup tcpdump -i eth1 port 3306 -s 65535 -x -nn -q -tttt > dbxx_sql_new.log &
過一段時間後,如1分鐘,終止tcpdump任務。
而後使用pt-query-digest進行分析。
./pt-query-digest --type=tcpdump --watch-server 12.12.12.12:3306 dbxx_sql_new.log > report_to_develper.rtf
對生產環境的採樣能夠採起如上的方法,好比每分鐘抓取5秒的網絡包,而後把分析結果入庫。
利用監控系統及時發現問題,通知DBA或研發人員線上的性能問題。
3)把分析過的SQL記錄到歷史信息表中,就能夠知道分析的SQL最後出現的時間,若是已經解決掉了,就不用再優化了。具體步驟以下。
第一步,在存放優化信息的數據庫中建立一個用戶用於存放信息。
GRANT CREATE,SELECT,INSERT,UPDATE,DELETE ON ptool.* to ptool@'%' IDENTIFIED BY 'ptool';
第二步,執行以下命令分析慢查詢日誌。
/home/mysql/scripts/pt-query-digest --create-review-table --reviewh=13.13.13.13,P=3305,u=ptool,p=ptool,D=ptool,t=query_review --create-review-history-table -- review-history h=13.13.13.13,P=3305,u=ptool,p=ptool,D=ptool,t=query_review_history --report-all /path/to/log3307/slowquery.log
以上命令若是是第一次運行,則會將信息存儲到指定的表中,之後再次運行時,若是表中的某條SQL的reviewed_by列已有設定值,那麼此工具就不會顯示標記了的SQL。
若是要顯示全部SQL,那麼須要使用選項--report-all。
若是有--report-all和query_review表(表中記錄的SQL及你添加的意見等信息),那麼生成的報告裏將帶有你檢查過的SQL的意見,這點會頗有用。
第三步,能夠運行以下命令查詢Top SQL。
SELECT * FROM `query_review_history` WHERE ts_max > '2012-09-20 00:00:00'ORDER BY ts_cnt DESC , query_time_sum DESC LIMIT 3;
能夠按照checksum(數據表裏的是十進制的顯示,報告裏的是十六進制的顯示方式)去數據表中查詢對應的SQL,記錄本身的優化意見,命令以下。
SELECT * FROM `query_review` WHERE CHECKSUM=0xB76366269B6B4973;
4)報告不記錄到歷史信息表中,只記錄簡單的信息。
/home/mysql/scripts/pt-query-digest --create-review-table --review h=13.13.13.13,P=3305,u=ptool,p=ptool,D=test,t=query_review /path/to/log3307/slowquery.log
存放信息的表須要咱們手動創建,或者添加選項--create-review-table。每次從新運行以上命令時,都會從新更新表內的值。好比最先、最近出現的時間。
5)使用pt-query-digest分析通用日誌和二進制日誌。
分析通用日誌示例以下。
pt-query-digest --type genlog general.log > /tmp/xxx.log
分析二進制日誌示例以下。
pt-query-digest --type binlog --group-by fingerprint --limit "100%" --order-by "Query_time:cnt" --output report --report-format profile /tmp/xxx.log
注意:/tmp/xxx.log日誌是文本形式的二進制日誌。
(3)pt-stalk
pt-stalk的語法格式以下:Usage: pt-stalk [OPTIONS]
即便咱們有了完備的性能收集程序,對於一些忽然的性能波動也仍然會難以捕捉,若是是偶發性的性能問題,幾天才發生一次,
那麼持續地對系統收集大量信息不只會顯得沒有必要並且還會耗費太多資源。
pt-stalk這個工具備助於解決此類問題,它能夠在必定的條件下被觸發,用於收集系統信息。
咱們能夠查詢SHOW GLOBAL STATUS命令結果繪製的圖形,查看是否某個變量發生了突變,而後選擇這個變量作一個啓動pt-stalk的條件,收集足夠的信息。
比較好的一個衡量的閾值是 Threads_running,
好比,咱們能夠將某個生產環境Threads_running的閾值設置爲20,pt-stalk每秒監控status的變量Threads_running,若是連續5秒都超過20,那麼就能夠開始收集統計信息了。
注意,觸發的閾值不能設置得過高,由於會致使不能發現故障,或者致使故障發生的真正緣由已通過去,固然,閾值也不能過低,由於可能會誤報警。
pt-stalk是一個後臺程序,默認咱們能夠經過文件/var/log/pt-stalk.log,查看pt-stalk的運行狀態。
以下命令將檢查pt-stalk的日誌。 tail -f /var/log/pt-stalk.log
2013_07_09_10_24_04 Check results: status(Threads_running)=55, matched=yes, cycles_true=1
2013_07_09_10_25_03 Check results: status(Threads_running)=51, matched=yes, cycles_true=1
2013_07_09_10_26_04 Check results: status(Threads_running)=44, matched=yes, cycles_true=1
2013_07_09_10_28_04 Check results: status(Threads_running)=62, matched=yes, cycles_true=1
2013_07_09_10_28_05 Check results: status(Threads_running)=57, matched=yes, cycles_true=2
2013_07_09_10_29_03 Check results: status(Threads_running)=46, matched=yes, cycles_true=1
2013_07_09_10_29_04 Check results: status(Threads_running)=56, matched=yes, cycles_true=2
pt-stalk將收集的數據默認放在目錄/var/lib/pt-stalk下,你能夠使用參數--dest指定你但願存放數據的目錄。
你還能夠使用--notify-by-email參數指定郵件報警聯繫人。
以下示例中,pt-stalk運行在後臺(--daemonize),監視SHOW GLOBAL STATUS中的Threads_running狀態,若是Threads_running的值超過了64,就將狀態信息記錄到日誌裏。
pt-stalk每秒鐘檢測一次Threads_running值,若是連續5次知足觸發條件,就開始收集主機和MySQL信息。
咱們使用--dest指定存放數據的目錄,
使用--disk-pct-free來定義磁盤的剩餘空間閾值,若是剩餘空間小於20%,則再也不進行數據收集。
--iterations可限制收集數據的次數,默認狀況下pt-stalk會永久執行。
--collect- tcpdump表示還要調用tcpdump收集網絡包信息。
pt-stalk --pid /path/to/pt-stalk.pid --dest /path/to/data --disk-pct-free 20 --log /path/to/log/pt_stalk.log --collect-tcpdump --function status \
--variable Threads_running --threshold 64 \
--iterations 2000 --notify-by-email=garychen\@db110.com --daemonize --user=root --password=your_password -S /tmp/mysql.sock
除了經常使用的threads_running,咱們還能夠使用SHOW PROCESSLIST的輸出值觸發pt-stalk,
例如「--function processlist--variable State--match statistics--threshold 20」表示,show processlist輸出中State列的值爲statistics的線程數若是超過20則觸發收集。
性能故障時刻,咱們應該儘量地收集操做系統和MySQL的信息,不只要收集正在執行的任務信息,還要收集正在等待資源的信息,由於咱們並不能肯定是執行慢仍是等待了太多資源。
這個工具還能夠調用tcpdump來收集網絡包信息,而後咱們再調用pt-query-digest進行分析,命令以下。
tcpdump -r 2013_04_30_18_20_48-tcpdump -nn -x -q -tttt | pt-query-digest --type tcpdump --watch-server ip:port >report.rtf
其餘的一些參數及說明以下:
--run-time:觸發收集後,該參數將指定收集多長時間的數據。默認是30秒。
--sleep:爲防止一直觸發收集數據,該參數指定在某次觸發後,必須sleep一段時間再繼續觀察並觸發收集。默認是300秒。
--cycles:默認狀況下pt-stalk只有連續5次觀察到狀態值知足觸發條件時,纔會觸發收集。
有了數據以後,咱們就可以使用pt-sift對收集的數據進行分析,這個工具將幫助咱們分析pt-stalk收集到的信息,它會自動下載其餘須要用到的工具。
(4)pt-sift
pt-sift的語法格式以下:
pt-sift FILE│ PREFIX│ DIRECTORY
若是存在/var/lib/pt-stalk,則默認讀取/var/lib/pt-stalk下的全部文件,不然讀取當前目錄下的文件。
若是是非默認目錄,則請指定本身的工做目錄,命令以下:./pt-sift /path/to/data
若是是指定文件名或前綴,則它會到默認目錄裏去查找。
例如以下命令:
./pt-sift /var/lib/pt-stalk/2012_09_07_00_00 #在默認目錄 /var/lib/pt-stalk裏查找 以 2012_09_07_00_00爲前綴的文件分析。
./pt-sift /var/lib/pt-stalk/2012_09_07_00_00_13 #在默認目錄裏查找 以 2012_09_07_00_00_13爲前綴的文件分析。
以下是pt-sift的一個輸出,這裏僅顯示磁盤信息。
(5)pt-align
功能:將文件內容按列對齊。
語法:pt-align [FILES]
用途:pt-alian也可正確地處理空白字符(如空格、TAB),咱們能夠用它來格式化和vmstat、iostat的輸出,移除一些不須要顯示的內容。
(6)pt-archiver
語法:pt-archiver [OPTION...] --source DSN --where WHERE
用途:pt-archiver可將MySQL數據庫中表的記錄歸檔到另一個表或文件中,也能夠直接進行記錄的刪除操做。
工做原理 :pt-archiver工具可以智能地選擇表上的索引,從源表中分批次找出符合WHERE條件的數據,
根據要求把表數據歸檔成csv格式或將表數據插入到歸檔表中,而後刪除源表中的數據(默認刪除)。
工做過程 :從源表SELECT數據,插入到新表或歸檔到文件,而後刪除源表的數據。經過這種方式,保證只有歸檔成功了才刪除源表的數據。
這個工具可用於遷移數據,能夠減小對線上OLTP應用的影響,它能夠小批量地把OLTP數據庫上的數據導入OLAP數據庫中。
也能夠將它寫入一個文件中,方便 使用LOAD DATA INFILE命令導入數據。咱們還能夠用它來實現增量的刪除操做。
注意:默認歸檔數據的同時會刪除生產庫上的數據,所以在生產環境中使用時必定要慎重。
示例1:從OLTP數據庫歸檔表tbl到OLAP數據庫,而且歸檔到一個文件中。
pt-archiver --source h=oltp_server,D=test,t=tbl --dest h=olap_server --file '/var/log/archive/%Y-%m-%d-%D.%t' --where "1=1" --limit 1000 --commit-each
示例2:刪除子表的孤立數據,這部分數據在父表中不存在關聯的信息。
pt-archiver --source h=host,D=db,t=child --purge --where 'NOT EXISTS (SELECT * FROM parent WHERE col=child.col)'
示例3:將test庫的userinfo表中id小於10000的記錄歸檔到/home/mysql/tmp/userinfo_archive_20131010.log文件中。
pt-archiver --source h=host,D=test,t=userinfo --user=root --password=your_password --file '/home/mysql/tmp/userinfo_archive_20131010.log' --where "id<=10000" -- commit-each
參數說明:
--limit:控制導出數據歸檔的粒度,默認是1。
--commit-each:控制在每批次歸檔數據的時候提交。
--no-delete:不刪除源表的數據。
--progress:每進行一次歸檔或刪除,都顯示所耗時間的信息,並能夠據此預估總時間。
--statistics:結束的時候給出統計信息,包括開始的時間點、結束的時間點、查詢的行數、歸檔的行數、刪除的行數,以及各個階段所消耗的總的時間和比例, 便於後續以此進行優化。
--columns:須要導出哪些列,列名用逗號隔開。
--sleep:在先後兩次導出之間sleep(休息)的時間。避免給服務器形成較大的壓力。若是同時設置了--commit-each選項,那麼提交和刷新文件的操做應在sleep以前發生。
--primary-key-only:只選擇主鍵列。對於刪除表數據的場景,該選項能夠避免取回整行數據,所以也更高效。
--ignore或--replace選項:使用insert ignore或replace語句可代替insert語句。
(7)pt-config-diff
語法:pt-config-diff [OPTION...] CONFIG CONFIG [CONFIG...]
功能:檢查配置文件和服務器變量之間的差別。
DBA有時變動了MySQL全局變量,但忘記了同步修改配置文件,這樣可能會致使隱患,由於有時重啓後,又使用了舊的配置,
另外,這個工具能夠用來在遷移或從新搭建環境的時候,確保新的遷移環境的配置和原來的生產環境的配置一致。
示例1:對比host1和host2的變量
pt-config-diff h=host1 h=host2
示例2:檢查本地實例和本地配置文件。
pt-config-diff u=root,P=3306,S=/tmp/mysql.sock,p=password /etc/my.cnf
示例3:對比兩個配置文件。
pt-config-diff /etc/my-small.cnf /etc/my-large.cnf
(8)pt-show-grants
語法:pt-show-grants [OPTION...] [DSN]
功能:導出權限的工具,方便咱們在配置主從、遷移數據庫的時候比對權限。
有時咱們並不想經過導出導入系統庫mysql來實現權限的配置,使用這個工具能夠生成更友好的賦權語句,咱們在目標庫上直接執行便可。
利用這個工具也能夠方便地回收權限。
示例1:導出權限。
pt-show-grants u=root,P=3306,S=/tmp/mysql.sock,p=password
示例2:查看每一個用戶的權限生成revoke收回權限的語句。
pt-show-grants --host='localhost' --user='root' --password='password' --revoke
(9)pt-summary
語法:pt-summary
功能:僅收集系統信息,它不是一個用於調優診斷的工具。
它能夠生成一個友好的報告,可展現系統的平臺、CPU、內存、磁盤、網絡、文件系統、進程等各類信息,讓你對基礎環境有一個很好的概覽。
pt-summary會運行許多命令去收集系統的狀態和配置信息,先將這些信息保存到臨時目錄的文件中去,
而後運行一些Unix命令對這些結果作格式化,建議用root用戶或有權限的用戶運行此命令。
示例1:$ ./pt-summary
(10)pt-mysql-summary
語法:pt-mysql-summary [OPTIONS] [-- MYSQL OPTIONS]
其中,「--」後的參數是傳遞給MySQL的。
功能:對MySQL的配置和STATUS信息進行彙總,所生成的報告能夠告訴咱們,當前系統上存在哪些MySQL實例,主機的通常信息,
對SHOW PROCESSLIST的一些分析總結,以及變量的設置,並對STATUS狀態變量進行採樣,顯示各類狀態變量的增量變化。
例子1:將彙總本地MySQL服務器的信息。
pt-mysql-summary -- --user=root --password='password ' --socket=/tmp/mysql.sock
其餘參數:
--sleep:採樣GLOBAL STATUS時,間隔多少秒,默認是10秒。
(11)pt-fifo-split
功能:模擬切割文件並經過管道傳遞給先入先出隊列(FIFO)而不用真正地切割文件。
當InnoDB使用load data的方式導入一個巨大的文件時,會建立一個很大的事務,產生不少UNDO,
若是異常回滾的話,會很耗時,可能會遠遠超過導入數據的時間,
因此更合理的方式是分批導入數據,那麼如何在不切割數據文件的狀況下達到分批導入數據的目的呢?使用Unix fifo便可。
例1: 以下是一個每次讀取一百萬行記錄的範例。
pt-fifo-split --lines 1000000 hugefile.txt while [ -e /tmp/pt-fifo-split ]; do cat /tmp/pt-fifo-split; done
例2: 每次讀取一百萬行,指定fifo文件爲/tmp/my-fifo,並使用LOAD DATA命令導入數據。
CREATE TABLE load_test ( col1 bigint(20) NOT NULL, col2 bigint(20) default NULL, key(col1), key(col2) ) ENGINE=InnoDB DEFAULT CHARSET=utf8
一個窗口: pt-fifo-split infile.txt --fifo /tmp/my-fifo --lines 1000000
另外一個窗口:
while [ -e /tmp/my-fifo ]; do
mysql -e "set foreign_key_checks=0; set sql_log_bin=0; set unique_checks=0; load data local infile '/tmp/my-fifo' into table load_test fields terminated by '\t' lines terminated by '\n' (col1, col2);"
sleep 1;
done
若是在mysql命令提示符下使用LOAD DATA導入數據將會出現亂碼,請設置SET character_set_database=字符集,或者修改LOAD DATA命令,添加character set語句,具體以下。
mysql -e "set foreign_key_checks=0; set sql_log_bin=0; set unique_checks=0; load data local infile '/home/mysql/db110.data' into table test.db110 character set gbk fields terminated by '\t' lines terminated by '\n' ;"
(12)pt-duplicate-key-checker
功能:查找重複的索引和外鍵。
這個工具會將重複的索引和外鍵都列出來,並生成刪除重複索引的語句。
其原理是檢查SHOW CREATE TABLE的輸出,查找重複或冗餘的信息。
冗餘指的是索引的字段是其餘索引的最左部分。
示例1:
./pt-duplicate-key-checker --user=root --password=password --socket=/tmp/mysql.sock
(13)pt-slave-delay
語法:pt-slave-delay [OPTION...] SLAVE-HOST [MASTER-HOST]
SLAVE-HOST [MASTER-HOST]能夠使用DSN語法。
功能:設置從服務器滯後於主服務器的時間。
MySQL同步在快速的網絡中是毫秒級的,若是有誤操做,從庫很快就變動了,對於一些頻繁進行,不是通過嚴格測試的升級,可能會帶來風險。
可考慮配置一個延遲複製的副本,以改善故障狀況下的可恢復性。
MySQL5.6版本已經支持延遲複製,若是是5.1版本,能夠用pt-slave-delay來設置延遲。
工做原理:經過啓動和中止複製SQL線程來設置從服務器落後於主服務器的指定時間。
默認是基於從服務器上relay日誌的二進制日誌的位置來判斷,所以不須要鏈接到主服務器。
檢查主庫傳輸過來的日誌的位置信息(能夠用SHOW SLAVE STATUS命令查看relay日誌),對比本地已經應用的日誌的位置信息,就能知道延遲的時間了。
若是IO線程不落後主服務器太多的話,這個檢查方式就能工做得很好。通常是經過--delay和--delay加--interval來控制的。
--interval間隔多久檢查一次,默認設置是1分鐘檢查一次,即每隔1分鐘檢查一次延遲,經過不斷啓動和關閉複製SQL線程來保持主從一直延遲固定的時間。
正常運行時,若是關閉了數據庫,那麼這個工具會每隔15秒重試一次鏈接,連續幾回以後,若是仍是不能鏈接,那麼就會異常退出。
示例1:如下命令將以daemon模式在後臺運行,從庫將保持一直滯後主庫1小時。
./pt-slave-delay u=xxxx,S=/tmp/mysql.sock,p=password --log /path/to/log/delay.log --daemonize
參數說明:
--delay:設置延遲時間,默認爲1小時。
--interval:設置檢查點頻率,每次檢查間隔多久,默認是1分鐘(1m)。
--delay和--interval可選的時間容許使用不一樣的單位,如,s秒、m分、h小時、d天。
--log:日誌,能夠檢查日誌輸出從而瞭解其原理和運行機制。
示例2:如下命令將運行這個工具10分鐘(默認是永久運行的),從庫保持一直滯後主庫1分鐘,每次檢查間隔15秒,所以理論上是延遲1分鐘15秒。
若是正在運行這個工具,並且這個工具已經中止了複製SQL線程,那麼當咱們按【Ctrl+C】退出這個工具時,它會友好地退出,意即它會啓動複製SQL線程,並恢復現場。
鏈接MySQL的用戶須要以下權限:PROCESS、REPLICATION CLIENT、SUPER。
若是啓動出錯,則會報錯以下:「Had to create DBD::mysql::dr::imp_data_size unexpectedly」,這時建議升級Perl。
pt-slave-delay --delay 1m --interval 15s --run-time 10m slavehost
(14)pt-online-schema-change
語法:pt-online-schema-change [OPTIONS] DSN
長期以來困擾DBA的一個問題是,MySQL在線修改表結構的能力很弱,對於大表修改表結構將會很耗時,還會影響到服務。
爲了減小對服務的影響,可能須要進行主從切換,或者選擇特定的時間進行升級。
MySQL新的版本5.6和5.7加強了數據庫在線修改表結構的功能,對於早期的版本,咱們能夠試試pt-online-schema-change這款工具。
這個工具的功能是實如今不鎖表的狀況下修改表結構。
這點對於在線應用很重要,這樣在修改表結構的同時,數據庫還能夠繼續提供讀寫服務。
工做原理 :建立一個和原表表結構同樣的新表,新表爲空數據,對新表進行表結構修改,
而後從原表中複製數據到新表,當數據複製完成之後就進行新舊錶的切換,新表被命名爲原表的名字,默認動做會將原表刪除。
在複製數據的過程當中,任何在原表中所作的更新操做都會更新到新表,由於這個工具會在原表上建立觸發器,觸發器會捕獲原表上的更新,並將它們更新到新表。
上述過程當中,原表複製數據到新表是分批分批覆制記錄到新表的,也有相關的參數能夠控制負載,如--max-load。
示例1:向表sakila.actor中添加一個列。
pt-online-schema-change --alter "ADD COLUMN c1 INT" D=sakila,t=actor
示例2:更改表的引擎爲InnoDB。
pt-online-schema-change --alter "ENGINE=InnoDB" D=sakila,t=actor
注意事項:
表須要有主鍵或惟一索引。
若是有外鍵,請仔細閱讀官方文檔。
須要確保原表中以前沒有觸發器。
利用此工具修改表結構,建議先進行備份。
切換新舊錶的時候,會致使鏈接中斷,須要確保應用中有重連的機制。
若是已經有長事務在操做這個表,那麼這個工具可能會由於等不到鎖而超時退出。
可能致使複製延時。
推薦使用獨立表空間,以便釋放空間。
(15)pt-kill
語法:pt-kill [OPTIONS] [DSN]
功能:kill掉知足某些條件的MySQL查詢。
pt-kill獲取SHOW PROCESSLIST的信息,對信息進行過濾,打印知足條件的鏈接,或者kill掉這些鏈接。
主要的目的是kill掉那些嚴重消耗資源的查詢,以保障服務的正常運行。
pt-kill也能夠檢查運行SHOW PROCESSLIST命令的輸出文件,打印知足條件的鏈接,這種狀況下,不須要鏈接MySQL去kill掉鏈接。
參數說明:
--busy-time:匹配運行時間超過busy-time的查詢。這些查詢的SHOW PROCESSLIST輸出的Command列爲Query,Time列大於busy-time指定的值,纔會被匹配。
--victims:指定哪些匹配的查詢會被kill掉或被打印。
有以下三個值:oldes:默認值,kill掉運行時間最長的查詢;all:kill掉全部查詢;all-but-oldest:kill掉除了運行時間最長的查詢以外的全部查詢。
有時咱們併發了許多一樣的查詢,這時咱們只須要確保最長運行時間的那條查詢可以執行成功便可,這種狀況下,咱們能夠使用all-but-oldest選項。
--kill:kill匹配條件的鏈接。
--print:打印kill語句,並不會真正地kill掉鏈接。若是--kill和--print都指定了,那麼不只要kill掉匹配的鏈接,也要打印被kill掉的鏈接。
pt-kill命令kill鏈接須要4個步驟,瞭解這4個步驟,有助於你理解這個工具的使用,並能準確選擇要kill掉的鏈接,4個步驟具體以下:
1)分組查詢到不一樣的類別。--group-by選項可控制分組。默認狀況下,這個選項沒有值,全部查詢都將被分組到一個默認的類中。
2)進行匹配。每一個類別都要進行匹配。首先,查詢會被不一樣的查詢匹配選項過濾,如--match-user。而後,查詢會被不一樣的類匹配選項過濾,如--query-count。
3)victim(kill候選者)選擇。若是一些查詢被過濾出來,那麼它能夠被kill掉,--victims控制哪些查詢會被kill掉。
通常狀況下,你可能會選擇kill掉運行時間最長的查詢,或者但願kill掉全部匹配到的查詢。
4)對選擇的查詢執行操做。如kill、print。
示例1:kill運行時間超過60s的查詢,默認狀況下kill最長時間的查詢,命令以下。
pt-kill --busy-time 60 --kill
示例2:僅僅打印運行時間超過60s的查詢,而不是kill掉它們,命令以下。
pt-kill --busy-time 60 --print u=root,S=/tmp/mysql.sock,p=password
示例3:每隔10s檢查一次sleep狀態的全部鏈接,並kill掉它們,注意參數--victims all,命令以下。
pt-kill --match-command Sleep --kill --victims all --interval 10
示例4:打印全部的登陸鏈接,命令以下。
pt-kill --match-state login --print --victims all
示例5:檢查SHOW PROCESSLIST輸出的文件,查看哪些鏈接匹配條件,命令以下。
mysql -e "SHOW PROCESSLIST" > proclist.txt
pt-kill --test-matching proclist.txt --busy-time 60 --print
示例6:kill掉運行時間超過120s且運行時間最長的那個鏈接,命令以下。
./pt-kill --busy-time 120 --match-command Query --match-db db_name --match-user user_name --kill --print u=root,S=/tmp/mysql.sock,p=password
--match-db和--match-user限定了數據庫名和用戶名,以避免誤操做。
示例7:kill掉運行時間超過120s的全部鏈接,命令以下。
./pt-kill --busy-time 120 --match-command Query --match-db db_name --match-user user_name --victims all --kill --print u=root,S=/tmp/mysql.sock,p=password
示例8:kill掉運行時間超過600s且正在建立臨時表的全部查詢,命令以下。
./pt-kill --busy-time 600 --match-command Query --match-db db_name --match-user user_name --match-state "Copying to tmp table" --victims all --kill
(16)pt-visual-explain
語法:pt-visual-explain [OPTION...] [FILE...]
功能:格式化EXPLAIN出來的執行計劃,並按照Tree方式輸出,以方便閱讀。
示例1:
pt-visual-explain <file_containing_explain_output>
pt-visual-explain -c <file_containing_query>
mysql -e "explain select * from mysql.user" | pt-visual-explain
(17)pt-slave-restart
功能:檢查MySQL的複製狀態,處理指定的MySQL複製錯誤。
比較經常使用的使用方式是,忽略指定的MySQL錯誤號,從新啓動複製SQL線程。
建議不要濫用這個工具,僅在你明確知道複製錯誤能夠忽略的時候,才使用這個工具忽略掉複製錯誤。
若是錯誤太多致使了嚴重的數據不一致,那麼建議重建整個從庫。
語法:pt-slave-restart [OPTIONS] [DSN]
參數說明:
--verbose:能夠顯示覆制錯誤。
--error-length:顯示覆制錯誤的長度。
--daemonize:後臺模式。
--log:當是daemonize模式時,輸出日誌到這裏。
--error-numbers:匹配了錯誤號才處理,錯誤代碼代號之間使用逗號進行分隔,對應SHOW SLAVE STATUS輸出裏的last_errno。
--error-text:匹配了錯誤文本才處理,對應SHOW SLAVE STATUS輸出裏的last_error。
--run-time:運行多久才退出,默認以秒爲單位,其餘單位s=seconds、m=minutes、h=hours、d=days。
--skip-count:當從新啓動salve時,應跳過多少條語句,默認值是1。
--sleep:每次檢查複製狀態的間隔休眠時間。
--until-master:重啓salve,直到從庫應用日誌到指定的主庫日誌位置。
例子1::檢查MySQL服務器的複製,跳過錯誤代碼爲1062的複製錯誤。
pt-slave-restart --verbose --error-numbers=1062 --run-time=60 u=root,S=/tmp/mysql.sock,p=password
(18)pt-diskstats
語法:pt-diskstats [OPTION...] [FILES] 按q可退出,按「?」顯示幫助。
功能:pt-diskstats是一個交互式的監控系統I/O的工具,這個工具相似於iostat,但顯示的信息更具可觀察性,它也能夠分析從其餘機器收集來的數據。
其實現的原理是讀取/proc/diskstats中的數據進行展現。
參數說明:
--interval:默認爲1,設置對/proc/diskstats採用的間隔。
--iterations:運行多少次,默認狀況下是永久運行。
示例1:pt-diskstats的一個輸出
./pt-diskstats --interval=5
./pt-diskstats --interval=2 --iterations 10
輸出項說明:
rd_s:每秒讀的次數,此數值是每秒平均讀次數,表徵了每秒實際發送到底層物理設備的讀請求的次數。
rd_avkb:每次讀的平均大小,單位是KB(千字節)。
rd_mb_s:每秒讀多少MB。
rd_mrg:請求在發送給底層實際物理設備前,被I/O調度合併的百分比。
rd_cnc:讀操做的平均併發。
rd_rt:讀操做的平均響應時間,以毫秒爲單位。
wr_s、wr_avkb、wr_mb_s、wr_mrg、wr_cnc、wr_rt對應寫操做,與rd_*相關的解釋相似。
busy:對應iostat的%util。
in_prg:正在進行請求的數目。
ios_s:物理設備的平均吞吐量,即IOPS(每秒IO),它是rd_s和wr_s的總和。
qtime:平均排隊時間,即請求在被髮送到物理設備前,在調度隊列裏等待的時間。
stime:平均服務時間,即實際物理設備處理請求的平均時間。
注意塊設備(block device)和物理設備(physical device)的區別:
塊設備,如/dev/sda1,應用程序以文件系統的方式訪問它,邏輯I/O發生在此。
物理設備指的是底層的實際物理設備,好比磁盤、RAID卡,物理I/O發生在此。
咱們所說的隊列指的是與塊設備相關的隊列,隊列保存讀寫請求直到這些請求被實際發送給物理設備爲止。
(19)pt-deadlock-logger
語法:pt-deadlock-logger [OPTIONS] DSN
功能:pt-deadlock-logger是一個死鎖檢測工具,適用於InnoDB引擎,能夠提取和記錄InnoDB的最近的死鎖信息。
工做原理:檢測死鎖(經過SHOW ENGINE INNODB STATUS\G;),而後直接打印死鎖信息,或者指定--dest參數將信息存入test庫下的一個表test.deadlocks中。
參數說明:
--iterations:迭代檢查多少次,如 --iterations 4 --interval 30表示檢測4次,每次間隔30s。
--run-time:運行此工具多久時間。這個參數的優先級比iterations更高,如--run-time 1m。
--interval:檢測死鎖的頻率,默認是30s。
--dest:指定存儲死鎖信息的數據庫表,須要預先建立表。
示例1:檢測死鎖,輸出至屏幕,檢測10次便可。
pt-deadlock-logger u=root,S=/tmp/mysql.sock,p=password --iterations 10
示例2:檢測死鎖,並把死鎖信息存入test庫的表中。
pt-deadlock-logger u=root,S=tmp/mysql.sock,p=password --dest D=test,t=deadlocks
示例3:檢測死鎖,並把死鎖信息存入另一個數據庫中。
pt-deadlock-logger SOURCE_DSN --dest DEST_DSN,D=test,t=deadlocks
示例4:運行4個小時,每次間隔30秒,在後臺運行,檢查死鎖信息中。
pt-deadlock-logger SOURCE_DSN --dest D=test,t=deadlocks --daemonize --run-time 4h --interval 30s
注意:頻繁調用SHOW INNODB STATUS,也可能對生產系統產生影響,對於負載較重的MySQL數據庫,建議每次間隔大於30s以上。
(20)pt-table-checksum
功能:pt-table-checksum這個工具的目的是在線檢測MySQL的主從一致性。
數據庫主從數據不一致的緣由可能以下:
從庫被誤寫了。
數據庫主機宕機致使MyISAM表損壞。
數據庫實例崩潰後,咱們指定了不許確的日誌點從新進行同步。
基於語句的複製。
一些Bug,特別是一些非核心的功能,好比存儲過程,可能會致使複製出錯,從而致使主從數據的不一致。
咱們須要確保主從數據是一致的。有時咱們在作了遷移或升級以後,也但願能有一個工具來確認主從數據的一致性。
工做原理:經過對比主從數據內容的CRC值來判斷數據的一致性,
它能夠分批次地校驗數據,以減小對生產的影響,它把一張表分爲若干個trunk,
若是一張表有 300萬行,分爲100個trunk,那麼每一個trunk就是有3萬行,它會鎖定這個trunk,進行CRC值的計算。
運行此工具時,若是有權限將會自動建立以下的表格。
CREATE TABLE checksums (
db char(64) NOT NULL, tbl char(64) NOT NULL, chunk int NOT NULL, chunk_time float NULL, chunk_index varchar(200) NULL,
lower_boundary text NULL, upper_boundary text NULL, this_crc char(40) NOT NULL, this_cnt int NOT NULL, master_crc char(40) NULL,
master_cnt int NULL, ts timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (db, tbl, chunk), INDEX ts_db_tbl (ts, db, tbl) ) ENGINE=InnoDB;
pt-table-checksum在主庫上生成REPLACE INTO語句,而後經過複製傳遞到從庫。
相似以下的語句,是基於語句級別的複製,將這條語句複製到從庫,從庫會執行這條語句,能夠知道,從庫上的這條記錄保存了從庫內容的checksum值。
checksum默認採用crc32值。
REPLACE INTO`percona`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc)
SELECT 'db_name', 'table_name', '1', NULL, NULL, NULL,
COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `id`, `name`, CONCAT(ISNULL(`name`)))) AS UNSIGNED)), 10, 16)), 0) AS crc
FROM `percona`.`garychen`
以上的crc列,簡單說明一下,它會把一個trunk裏面的每一行數據的全部字段都拼成一個String,而後對String取32位校驗碼,
而後對這個trunk內全部計算好的校驗碼進行異或操做,從十進制轉換成十六進制。
在主庫中UPDATE更新master_src的值,運行命令相似以下的語句。
UPDATE `percona`.`checksums` SET chunk_time = '0.000563', master_crc = '31012777', master_cnt = '4'
WHERE db = 'db_name' AND tbl = 'table_name' AND chunk = '1'
這個操做,一樣會被複制到從庫。
由上述示例能夠得知,經過檢測從庫上的this_src和master_src列的值能夠判斷複製是否一致。命令相似以下的語句。
SELECT db, tbl, SUM(this_cnt) AS total_rows, COUNT(*) AS chunks FROM percona.checksums
WHERE ( master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc)) GROUP BY db, tbl;
能夠使用pt-table-checksum--explain查看工具是如何檢查表的。
它能夠檢測到從庫,並自動鏈接它們。自動鏈接從庫有多種辦法,能夠使用--recursion-method來指定,
默認是PROCESSLIST,即經過檢查SHOW PROCESSLIST 裏的輸出來判斷從庫,而後去鏈接對應的從庫。
host方法是利用SHOW SLAVE HOSTS的輸出信息判斷從庫,但這種方法在低版本中支持得很差。
你也能夠創建一個表存儲從庫的信息,經過檢索這個表來鏈接從庫進行數據比對。
它僅針對一臺服務器執行checksum操做,一次只針對一個表進行checksum操做。若是顯示有不少表,那麼--replicate-check-only可僅顯示存在差別的表。
若是被徹底終止了,能夠使用--resume選項繼續執行,你也能夠使用Ctrl加C退出。
示例1:chunk的大小也是能夠動態調整的,調整的依據是checksum操做在必定時間內能夠完成。
./pt-table-checksum h=ip,P=3306,u=test_gary,p=password --databases=db_name --tables=tbl_name --recursion-method=processlist
選項說明:
--max-lag:最大延遲,超過這個就等待。
--max-load:最大負載,超過這個就等待。
--databases:只檢查某些庫。
--tables:只檢查某些表。
注意事項:
主從數據庫的schema應該一致,不然複製可能會失敗。
使用的時候應選擇在業務低峯期運行,由於運行的時候會形成表的部分記錄被鎖定。
雖然操做是對trunk逐個進行的,可是它會對每一個trunk作SELECT FOR UPDATE,這樣作主要是擔憂作checksum的時候會有寫入,因此各個trunk都不適合太大。
pt-table-checksum提供了多種手段以確保儘可能不會對生產環境形成影響,你能夠使用--max-load來指定最大負載,若是達到最大負載,就暫停運行。
你也能夠設置超時時間innodb_lock_wait_timeout。
若是發現有不一致的數據,則能夠使用pt-table-sync工具來進行修復。
若是表中沒有主鍵或惟一索引,或者沒有合適的索引,或者處於其餘不適合檢查的狀況下,那麼工具可能會忽略這個表。
(21)pt-table-sync
語法:pt-table-sync [OPTION...] DSN [DSN...]
功能:進行數據表的同步。
工做原理:對比主從庫之間的差別,在主庫上執行數據的更改(使用REPLACE INTO語句或DELETE語句),再同步到從庫上。
對於主庫上存在,從庫上不存在的數據,執行REPLACE INTO語句。
對於從庫上存在,主庫上不存在的數據,執行DELETE語句。
對於在主庫、從庫上同時存在,但數據不一致的狀況,基於主庫如今的數據執行更改操做(REPLACE INTO語句),因此REPLACE INTO語句不會更改主庫上的數據。
這個工具會更改數據,因此若是須要使用這個數據在不一樣的MySQL庫之間進行數據同步,那麼建議先進行數據備份。
主從庫實例可能會由於一些誤操做或軟硬件異常而致使數據出現不一致的問題,而使用這個工具能夠修復主從庫之間的數據差別。
使用這個工具修復主從庫的不一致問題,必須先保證被修復的表上有主鍵 或惟一鍵。
參數說明:
--execute:執行變動。
--print:僅打印變動語句,能夠把--execute參數換成--print先查看會變動什麼數據。
--replicate:指定一個同步列表,--replicate指定的表裏存儲了須要同步的表的信息。
這個表實際上就是pt-table-checksum工具生成的校驗信息,咱們能夠先利用pt-table-checksum工具進行校驗,而後利用校驗結果進行同步。
--sync-to-master:指定從庫,同步到主庫。
--ignore-databases:忽略同步的數據庫列表,以逗號分隔。
--ignore-engines:忽略同步的引擎列表,以逗號分隔。
--ignore-tables:忽略同步的表,以逗號分隔。
示例1:咱們假設host1是主庫,host2是從庫,端口爲3306。
1)先使用pt-table-checksum進行校驗,默認將校驗結果存儲在percona.checksums中。
./pt-table-checksum --user=user --password=password --host=host1 --port=port --databases=db_name --tables=tbl_name --recursion-method=processlist
2)根據校驗結果,修復從庫中的數據。
./pt-table-sync --execute --replicate percona.checksums --sync-to-master h=host2,P=3306,u=user,p=password
3)修復後,使用第步驟1)的語句從新校驗一次。
注意:
使用pt-table-sync的風險比較大,對於生產環境,建議使用pt-table-checksum進行校驗,若是有數據不一致的問題,則考慮重建從庫;
若是要使用pt-table-sync進行數據同步,則建議仔細閱讀官方文檔,瞭解它的限制和可能產生的影響,以免影響生產環境或修復數據不成功。
(22)pt-query-advisor
語法:pt-query-advisor /path/to/slow-query.log
功能:分析慢查詢日誌或generel日誌,並給予建議。
輸出的報告中包含了3種級別的提示,note級別、warn級別和critical級別。
note級別 :
應該使用「table as 別名」的方式,而不是「table 別名」的方式,由於使用as可讀性更好。
別名不要和原來的表名同樣。
INSERT INTO語句應該顯式地指定列名,如INSERT INTO tbl(col1,col2)VALUES...。
日期/時間值須要用引號括起來。如WHERE col<'2012-02-12'
應該使用「<>」而不是「!=」。由於「!=」不標準。
warn級別:
參數儘可能不使用前導通配符,好比 LIKE '%name' ,這樣的方式是用不到索引的,MySQL的索引通常是前綴索引。
SELECT語句若是沒有WHERE條件,則有可能會致使檢索太多的記錄。
多表查詢GROUP BY或ORDER BY子句的列不在同一個表中會致使使用臨時表(temporary table)和文件排序(filesort)。
不要使用SQL_CALC_FOUND_ROWS,這種方式檢索數據效率很低,會須要檢索全部的記錄以肯定記錄的總數。
critical級別 :
不要混合ANSI標準的JOIN方式和MySQ中的JOIN語法,不然容易致使用戶混淆。
能夠使用ON或USING語句來指定一個簡單的鏈接,被鏈接的列在ON或USING子句中列出,而WHERE子句中能夠列出附加的選擇條件。
(23)pt-mext
功能:用於查看SHOW GLOBAL STATUS信息,能夠增量(-r選項)顯示,逐列進行顯示。
示例1:將每隔10秒執行一次SHOW GLOBAL STATUS,執行4次, 並將結果合併到一塊兒查看。
pt-mext -r -- mysqladmin ext -uroot -p111111 -i 10 -c 4
(24)pt-upgrade
功能:用於在多個MySQL實例上執行查詢,並比較查詢結果和耗時。這個工具在進行數據庫版本升級的時候會頗有用。
語法:pt-upgrade [OPTION...] DSN [DSN...] [FILE]
示例1:查看慢查詢在不一樣主機實例上的運行效果
pt-upgrade h=host1 h=host2 slow.log
示例2:比較host2和host1的結果文件
pt-upgrade h=host1 --save-results host1_results/ slow.log
pt-upgrade host1_results1/ h=host2
(25)pt-find
功能:pt-find命令能夠查找MySQL中的表,並執行一些操做,這個工具相似於咱們操做系統下的find命令。默認的操做是打印數據庫名和表名。
示例1:打印一天之前建立的表,注意,僅對MyISAM有效。
pt-find --ctime +1 --engine MyISAM
示例2:查找InnoDB引擎的表,並轉化爲MyISAM表。
pt-find --engine InnoDB --exec "ALTER TABLE %D.%N ENGINE=MyISAM"
示例3:查找test庫和junk庫中的空表,並刪除之。
pt-find --empty junk test --exec-plus "DROP TABLE %s"
示例4:查找大於5GB的表。
pt-find --tablesize +5G
示例5:對全部表都按照數據佔用空間大小(數據+索引)進行排序。
pt-find --printf "%T\t%D.%N\n" | sort -rn
示例6:把數據表的size信息存放到表中。
pt-find --noquote --exec "INSERT INTO sysdata.tblsize(db, tbl, size) VALUES('%D', '%N', %T)"
16.3 調優方法論
16.3.1 性能調優的誤區
許多人犯的錯誤可能僅僅只是由於本身熟悉一些工具、知道一些命令,就處處使用它,而無論是什麼場合。
特別是初級工程師,由於瞭解的命令和方法有限,他們更容易這樣作。
還有些人喜歡去網上尋找答案,可是一些問題的解決方案,特別是涉及一些商業廠商的軟硬件,網上並無標準的答案,只有原廠工程師才掌握處理這些問題的方案,
並且,若是是緊急處理性能問題,上網查找極可能費力不討好。
有些人不清楚性能問題到底出如今哪,會嘗試修改不一樣的參數配置,而後查看效果怎麼樣,這樣的調優不但耗時,還可能給生產系統帶來隱患甚至致使生產環境異常。
有些人每每把問題歸咎於其餘環節、其餘團隊。
好比,懷疑是網絡的問題,懷疑是數據庫的問題,若是你懷疑是其餘團隊、其餘環節出了問題,
那麼你應該說明下本身是如何分析、如何查找和爲何懷疑的,這樣能夠更有助於溝通,而不是浪費了其餘部門的時間和精力。
全部以上出現的問題,都是由於沒有必定的規則指引,沒有按照必定的方法論來處理問題。
方法論包括了一些定量分析和確認疑問的方法,標識了哪些是最重要的性能問題。
它能夠幫助性能分析者定位問題,告訴咱們應該從哪裏開始,應該經過哪些步驟來定位問題。
對於初學者,能夠按照方法論逐步來定位問題,對於專家和熟手,能夠將方法論做爲一個檢查列表,確認咱們沒有忽視一些細節。
16.3.2 調優指引
當發生性能問題時,咱們須要知道從哪裏開始咱們的分析,應該收集什麼樣的數據,咱們應該如何分析這些數據。以下是一些調優指引。
1)首先,咱們須要定義調優的目標。
在調優以前,咱們須要設定咱們的目標,好比:資源使用率、延時、吞吐率。要依據你的業務、服務協議等級和服務標準量化你的性能調優所能達到的效果,
例如:平均響應時間小於5ms,99%的響應時間小於10ms。
肯定調優的目標以後,咱們再經過各類方式找到系統的瓶頸所在,而後優化它們。
2)咱們須要瞭解咱們的數據流,瞭解咱們的物理部署,這樣咱們纔能有意識地針對整個系統進行調優。
3)影響服務性能的主要因素從大到小大體是:架構和設計、應用程序、硬件、數據庫和操做系統。
高性能的服務是設計出來的,而不是調優出來的,而且,若是你的架構設計良好,那麼不須要怎麼調優,調優也會更加容易。
4)大規模、高性能的服務每每不是一蹴而就的,須要在後期不斷持續地迭代優化,甚至調整架構。
一個優秀的架構師有一個很重要的素質,那就是:在合適的時間以合理的成本介入進行調整優化。
5)性能調優有兩個方向,一個是讓工做作得更快,一個是讓工做作得更少。針對數據庫來講,就是要儘可能減小對數據庫的訪問,使用最快的路徑訪問數據。
6)DBA須要從系統資源使用和應用訪問的雙重角度去考慮問題,應用程序開發人員每每更關注程序的負載狀況,而系統管理員每每更關注資源的使用狀況。
做爲一名DBA,須要可以同時從這兩個角度去考慮問題。
從資源使用的角度進行分析,咱們經常使用的一些指標有IOPS、吞吐率、利用率和飽和度。
從工做負載的角度進行分析,咱們經常使用的指標有吞吐率和延時。
對工做負載的分析要求咱們熟悉工做負載的屬性,具體負載作了什麼?
好比對於數據庫訪問, 包括客戶端主機/IP、數據庫名、數據表名、查詢字符串,經過熟悉這些狀況,咱們能夠肯定哪些工做是不須要作的,是能夠消除的,哪些工做是能夠加快的。
咱們還可能須要深刻到應用的代碼細節裏去優化。
7)性能調優是一種取捨,咱們須要意識到性能調整是有權衡取捨的,性能好、成本低、快速交付這三個目標每每不可兼得。
許多公司的項目選擇了成本低和快速交付,而把性能問題留待之後去解決,可是一旦你的架構存在問題,你將很難進行調優,反而不得不付出昂貴的調整成本。
在許多互聯網公司,更廣泛存在的一種狀況是項目的時間是固定的,甚至要趕在對手發佈以前進行發佈,
若是選擇了成本低、性能好的決策,那麼如期交付每每很難作到,這個時候若是仍然按照原定的進度計劃交付軟件,則每每意味着軟件和服務的穩定性會降低。
在物理組件之間也有權衡取捨,好比有些應用CPU很空閒,內存很緊張,那麼能夠使用CPU壓縮數據以節省內存的使用。
參數的調整也有權衡取捨,好比文件系統的塊大小,較小的塊,接近應用的訪問I/O大小,更適合隨機訪問的應用負載。
而較大的塊,更適合一些大的操做,好比備份。好比,小的網絡緩衝區能夠減小每一個鏈接的內存開銷,使系統更好地擴展,而大的網絡緩衝區則能夠提高網絡吞吐率。
8)性能調優越靠近任務處理的環節就越有效,由於它們更瞭解數據,對於施加負荷的應用程序而言,針對應用程序自身的調優最有效。
對於一個普通的基於數據庫的網站服務而言,咱們的軟件棧是應用程序→數據庫→系統調用→文件系統→存儲。
對存儲設備進行優化能夠提高I/O能力,但這是對最底層的優化,它的改善反映到更上層的應用的改善,每每是打了折扣的,
好比存儲設備的性能提高了1倍,也許應用的性能才提高20%。
形成這種現象的根本緣由是越遠離應用層,越不熟悉數據是如何存取的,因此針對存儲設備所作的優化,相對於應用程序自身的調優,可能對於應用的性能改善並無太大的用處。
9)參數的調整可能會立刻見效,但極可能隨着軟硬件環境的變動,又變得再也不適合,甚至還會對性能起副作用。
因此,若是不是必需要調整,那麼就不要去調整。更少的參數配置,使用默認的參數配置也意味着更少的維護成本。
網上有許多調優的建議和分享。這些分享每每都是基於特定的環境的,或者是基於特定的場合,而在以後,他們又有了調整,卻每每沒有繼續分享,
一些調優的建議,特別是互聯網上的文章,以訛傳訛,極可能存在某種隱患,爲了保持系統的穩定,除非咱們肯定必需要更改,不然建議不要修改。
更合適的策略是,關注業內的專家,看看他們的分享,看看哪些參數是能夠在咱們的系統上進行修改的。作一些記錄,一旦有須要,咱們再採納也不遲。
10)咱們不只要標識出哪些問題多是須要調優的,也要衡量修復這些問題所帶來的收益。
若是修復一個問題,對於總體系統的貢獻不大,那麼投入時間和精力去調優可能不是一個好的主意。
16.3.3 調優步驟
調優的具體步驟以下。
1)收集信息。
若是你是一個支持工程師,或者是一個獨立的數據庫諮詢顧問,那麼當有性能問題發生時,你須要和客戶確認一些信息。
以下是要問的一些基本問題,經過這些問題,你每每能夠很快就能肯定緣由,或者肯定一個合適的解決方案,或者肯定下一步應該怎麼作。
你爲何認爲有性能問題,你是如何判斷的?
系統以前是好的嗎?最近有作過什麼軟硬件的變動嗎?業務流量、負載有變化嗎?
問題能夠使用延時或運行時間來描述嗎?
影響到了其餘的用戶和程序嗎?
軟硬件的環境是什麼樣的?版本/配置/參數是什麼樣的?
若是咱們的線上有性能問題,那麼咱們須要收集負載信息和資源使用狀況。
咱們還可能須要檢查配置,好比出現網絡問題,好比有時網卡工做在100MB的模式下而不是1000MB的模式,好比RAID陣列壞了一塊盤,
好比操做系統、應用程序、固件的版本有變化,好比由於程序配置錯誤,訪問了遠程資源而不是本地資源。
2)分析問題。
在問完這些問題以後,咱們大體有了診斷的思路。這時咱們能夠推測有多是哪些因素致使了性能問題。
3)驗證性能問題的緣由。
以後咱們再進行一些驗證測試工做來驗證咱們的想法。
好比MySQL的InnoDB buffer pool對性能的影響很大,咱們假定是InnoDB buffer pool不夠才致使的性能惡化,
咱們能夠部署一個新的環境,增大InnoDB buffer pool,進行壓力測試,這個時候,咱們會發現性能有所改善,從數據庫的狀態信息咱們也能夠發現物理讀減小了許多。
經過不斷地猜想和驗證,咱們能夠逐步縮小範圍,定位到真正的致使性能惡化的因素上。
4)進行調整。
5)觀察性能調整的效果。
16.3.4 調優的方法
(1)USE方法
有一種調優的方法叫USE方法。其基本思路是,對於每項資源,檢查其錯誤、利用率和飽和度。
在資源利用率很高或趨向飽和時,若是出現瓶頸,性能下降,那麼這種狀況下,USE的分析方法將會最有效。
咱們首先檢查錯誤,對於錯誤,須要仔細就調查其產生緣由。錯誤極可能會致使性能下降,若是錯誤是不能夠被重現的,那麼你可能不能及時發現錯誤。
而後咱們檢查資源利用率,檢查飽和度,在檢查資源利用率和飽和度的過程當中,咱們逐步縮小範圍,最終定位到問題所在。
(2)延遲分析法
找出響應最慢的環節,這個環節將被再次細分,再找出最影響時間的因素,並不斷循環,直到最終解決問題。
小結:本章介紹了一些性能調優的基礎概念、理論和經常使用的診斷工具。綜合知識、工具、經驗、意識,咱們纔可能成爲一名性能調優專家。其中一些工具和命令的解釋是摘錄自網上的信息,筆者作了一些修正,但仍然可能有錯漏之處,建議不熟悉命令的讀者,好好閱讀man幫助,這是筆者認爲學習命令的最好的一種方法。Percona Toolkit包含了不少工具,平時咱們常用的可能只有寥寥幾個工具。筆者沒有對全部工具作實際驗證,讀者應該牢記一點,若是工具可能修改生產環境中的數據,那麼就必定要慎重使用,建議首先備份好數據。