MySQL SYS CPU高的案例分析(一)
【現象】
最近關注MySQL CPU告警的問題時,發現有一種場景,有一些伺服器最近都較頻繁的出現CPU告警,其中的現象是 SYS CPU佔比較高。
下面的截圖來源於“MySQL CPU報警”採集的檔案
【問題分析】
可以分析出這伺服器CPU升高的原因是由於表的高併發寫入引起。優化方案通常是通知開發停止寫入或降低寫入頻率。
究竟是什麼原因導致高併發寫入時CPU sys的佔比這麼高。
從採集的【Perf Stat】指標看到CPU有大量消耗是集中kernel的spin_lock上,推測sys的消耗佔比是由spin lock引起的
同時從這個系統呼叫中也可以比較清晰的看出一個INSERT語句的執行過程(只是執行路徑上的部分關鍵函式),簡單整理如下:
insert當獲取不到rw-lock時,保持spin lock,進入短暫等待。高併發的大量訪問出現資源競爭,大量執行緒出現spin lock及context switch,導致CPU飆升。
為了防止自旋鎖迴圈過快,耗費CPU,MySQL中引入了innodb_spin_wait_delay引數,具體可參考下面的官方手冊
https://dev.mysql.com/doc/refman/5.6/en/innodb-performance-spin_lock_polling.html
【問題重現】
在測試環境中,啟用1000個併發執行緒模擬高併發寫入的場景
1、innodb_spin_wait_delay和innodb_sync_spin_loops保持預設值不變
CPU idle在18%左右,sys佔比40%多,TPS在1.5W左右
2、將變數適當增大SET GLOBAL innodb_spin_wait_delay=18;
(注意:18是在Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz 40核的CPU經過多次測試得出的相對合理的值,建議該值大小不要超過24)
可以觀察到CPU idle在15%左右,sys佔比降到20%多,TPS增加到1.75W左右,MySQL的插入效能約提升了16.7%
【結論】
對於MySQL高併發寫入的場景,我們可以通過微調innodb_spin_wait_delay引數,減少kernel的spin_lock消耗,降低CPU的sys佔比,從而提升MySQL的TPS處理能力。