在日常工作中,發現 mysql 的狀態不太對勁的時候,一般都會看看監控指標,很多時候會看到熟悉的一幕:cpu 使用率又爆了。本文將給大家介紹 mysql 和 cpu 之間的關係,對此有一定的了解之後可以更準確的判斷出問題的原因,也能夠提前發現一些引發 cpu 問題的隱患。
以 linux 的 top 命令為例,效果如下:
在 %cpu 這一列就展示了 cpu 的使用情況,百分比指代的是總體上占用的時間百分比:
通常情況下,我們討論的 cpu 使用率過高,指的是 %us 這個指標,監控裡面的 cpu 使用率通常也是這個值(也有用其他的方法計算出來的,不過簡單起見,不考慮其他的情況 )。其他幾個指標過高也代表出 mysql 的狀態異常,簡單起見,這裡主要還是指 %us 過高的場景。
mysql 是單程序多執行緒的結構,意味著獨佔的 mysql 伺服器裡面,只能用 top 命令看到一行資料。
這裡能看到的是 mysql 的程序 id,如果要看到執行緒的情況,需要用top -h
在這裡能看到的是 mysql 各個執行緒的 id,可以看到 mysql 在啟動之後,會建立非常多的內部執行緒來工作。
這些內部執行緒包括 mysql 自己用來刷髒,讀寫資料等操作的系統執行緒,也包括處理使用者 sql 的執行緒,姑且叫做使用者執行緒吧。使用者執行緒有乙個特殊的地方:程式端傳送到 mysql 端的 sql,只會由乙個使用者執行緒來執行(one-thread-per-connection),所以 mysql 在處理複雜查詢的時候,會出現「一核有難,多核圍觀」的尷尬現象。
參考 %us 的定義,對於 linux 系統來說,mysql 程序和它啟動的所有執行緒都不算核心程序,因此 mysql 的系統執行緒和使用者執行緒在繁忙的時候,都會體現在 cpu 使用率的 %us 指標上。
mysql 幹什麼的時候,cpu 會 100%?從前文的分析來看,mysql 主要是兩類執行緒占用 cpu:系統執行緒和使用者執行緒。因此 mysql 獨佔的伺服器上,只需要留意一下這兩類執行緒的情況,就能 cover 住絕大部分的問題場景。
系統執行緒
在實際的環境中,系統執行緒遇到問題的情況會比較少,一般來說,多個系統執行緒很少會同時跑滿,只要伺服器的可用核心數大於等於 4 的話,一般也不會遇到 cpu 100%,當然有一些 bug 可能會有影響,比如這個:
mysql bug
雖然情況比較少,但是在面對問題的常規排查過程中,系統執行緒的問題也是需要關注的。
使用者執行緒
提到使用者執行緒繁忙,很多時候肯定會第一時間憑經驗想到慢查詢。確實 90% 以上的時候都是「慢查詢」引起的,不過作為方**,還是要根據分析再去得出結論的~ 參考 us% 的定義,是指使用者執行緒占用 cpu 的時間多少,這代表著使用者執行緒占用了大量的時間。
一方面是在進行長時間的計算,例如:order by,group by,臨時表,join 等。這一類問題可能是查詢效率不高,導致單個 sql 語句長時間占用 cpu 時間,也有可能是單純的資料量比較多,導致計算量巨大。另一方面是單純的 qps 壓力高,所以 cpu 的時間被用滿了,比如 4 核的伺服器用來支撐 20k 到 30k 的點查詢,每個 sql 占用的 cpu 時間並不多,但是因為整體的 qps 很高,所以 cpu 的時間被佔滿了。
分析完之後,就要開始實戰了,這裡根據前文的分析給出一些經典的 cpu 100% 場景,並給出簡要的定位方法作為參考。
ps:系統執行緒的 bug 的場景 skip,以後有機會再作為詳細的案例來分析。
慢查詢
在 cpu 100% 這個問題已經發生之後,真實的慢查詢和因為 cpu 100% 導致被影響的普通查詢會混在一起,難以直觀的看 processlist 或者 slowlog 來發現元凶,這時候就需要一些比較明確的特徵來進行甄別。
從前文的簡單分析可以看出來,查詢效率不高的慢查詢通常有以下幾種情況:
ps:1000 只是個經驗值,具體要根據實際業務情況來定。
計算量大
這一類問題通常是因為資料量比較大,即使索引沒什麼問題,執行計畫也 ok,也會導致 cpu 100%,而且結合 mysql one-thread-per-connection 的特性,並不需要太多的併發就能把 cpu 使用率跑滿。這一類查詢其實是是比較好查的,因為執行時間一般會比較久,在 processlist 裡面就會非常顯眼,反而是 slowlog 裡面可能找不到,因為沒有執行完的語句是不會記錄的。
這一類問題一般來說有三種比較常規的解決方案:
讀寫分離,把這一類查詢放到平時業務不怎麼用的唯讀從庫去。
在程式段拆分 sql,把單個大查詢拆分成多個小查詢。
使用 hbase,spark 等 olap 的方案來支援。
高 qps
這一類問題單純的就是硬體資源的瓶頸,不論是 row_examined/rows_sent 的比值,還是 sql 的索引、執行計畫,或者是 sql 的計算量都不會有什麼明顯問題,只是 qps 指標會比較高,而且 processlist 裡面可能什麼內容都看不到,例如:
processlist
實際上 cpu 100% 的問題其實不僅僅是單純的 %us,還會有 %io,%sys 等,這些會涉及到 mysql 與 linux 相關聯的一部分內容,展開來就會比較多了。本文僅從 %us 出發嘗試梳理一下排查&定位的思路和方法,在分析 %io,%sys 等方面的問題時,也可以用類似的思路,從這些指標的意義開始,結合 mysql 的一些特性或者特點,逐步理清楚表象背後的原因。
本文由部落格一文多發平台 openwrite 發布!
mysql 占用cpu過高
mysql 最近因使用者訪問量的增大和資料的增多,導致占用cpu過大,甚至可達100 所以,在網上找了些資料,進行cpu的優化 1.修改my.ini的 tmp table size 原來的 tmp table size 竟然為18m 汗.將其值修改為200m tmp table size 200m2...
Mysql 占用cpu資源高的分析
在伺服器上執行命令,將 mysql 當前的環境變數輸出到檔案 output.txt d web mysql mysqld.exe help output.txt 發現 tmp table size 的值是預設的 32m,於是修改 my.ini,將 tmp table size 賦值到 200m d ...
mysql占用CPU超過100 解決過程
2017年12月2日上午,將學校新聞網2015年之前的45000多條記錄遷移到了新 的mysql資料庫,新 上有2015年1月1日之後的9000多條記錄,資料量一下子增加了5倍。2017年12月3日晚上9點多,有領導和老師反映新聞網無法訪問,立即登入伺服器進行排查。一 使用top命令看到的情況如下 ...