1. 程式人生 > >效能分析之IO分析-jbd2引起的IO高

效能分析之IO分析-jbd2引起的IO高

 

背景:請事假在外中,聽平臺組同事反饋了一個問題,在往生產資料庫中匯入部分資料時會造成客戶端的訪問超時,初步定位是因為伺服器磁碟佔用IO過高,導資料時IO會飆升到100%,因此引起了不少資料庫的慢查詢操作導致客戶端響應超時,無奈只好暫時停止了匯入資料的指令碼,同時也延誤了針對這部分資料的生產測試工作。於是我第二天回到公司就投入了對這個問題的跟蹤定位工作。

環境描述:

  • 作業系統

    wKioL1PzHbih3dckAABqlzu8NXs262.jpg

  • 檔案系統

    wKiom1PzHLOyItieAADf6Fm1BEg633.jpg

  • 資料庫

    wKiom1PzHMOg31Y7AADJcKOXs80235.jpg

首先我們資料庫某最大表的資料也不過300w多條,對於MySQL來說還是能夠正常處理的。而且客戶端併發量也不過1K多,資料庫的TPS也未過百,我先後使用了top,iostat監測到的IO利用率確實都已經達到極限了。最後使用iotop這個工具發現了一個吃IO的罪犯jbd2

wKioL1PzHf2g6lTuAADhxOHRieM865.jpg

Overview
The Journaling Block Device (JBD) provides a filesystem-independent interface for filesystem journaling. ext3, ext4 and OCFS2 are known to use JBD. OCFS2 starting from linux 2.6.28 and ext4 use a fork of JBD called JBD2.

可以知曉它的主要功能是向檔案系統寫日誌。那麼肯定是由於對檔案系統的操作太頻繁導致的IO壓力過大,問題這是個系統程序,是系統問題還是?

目前我這臺伺服器上只有一個應用需要大量操作IO,那就是MySQL資料庫,會不會由他導致的?懷著這個疑問我用google將mysql和jbd2聯合作為關鍵字進行搜尋,得到了這麼一個線索sync_binlog,innodb_flush_log_at_trx_commit這兩個mysql的配置項。頓時我彷彿想起了什麼,於是翻到

《高效能MySQL》這本書的第10章——複製的章節(從上面的環境描述中可以看到我使用了MySQL的主主複製)找到了對sync_binlog的說明

wKioL1PzHhLDWouAAAJT10pjdMs726.jpg

那麼innodb_flush_log_at_trx_commit呢?

  • 如果innodb_flush_log_at_trx_commit設定為0,log buffer將每秒一次地寫入log file中,並且log file的flush(刷到磁碟)操作同時進行.該模式下,在事務提交的時候,不會主動觸發寫入磁碟的操作。

  • 如果innodb_flush_log_at_trx_commit設定為1,每次事務提交時MySQL都會把log buffer的資料寫入log file,並且flush(刷到磁碟)中去.

  • 如果innodb_flush_log_at_trx_commit設定為2,每次事務提交時MySQL都會把log buffer的資料寫入log file.但是flush(刷到磁碟)操作並不會同時進行。該模式下,MySQL會每秒執行一次 flush(刷到磁碟)操作。

由於我們的業務資料的特點,對資料可靠性並不如金融、訂單系統那麼高於是在權衡下就把sync_binlog設定為每500次重新整理一次磁碟,而將innodb_flush_log_at_trx_commit設定為2,再用iotop等工具檢視系統IO情況,大大降了下來。好吧,這個借刀殺IO的罪犯終於找到並被處理了。

後記:在這次處理問題的過程中有兩個小插曲。

  1. 某領導找來幾個人對此問題進行會診,有猜測伺服器資源不夠的,有猜測指令碼問題的,有猜測資料庫本身效率底下的…我個人非常非常反感在沒有經過效能和監控和資料的分析而憑空猜測問題的做法。我希望給所有靠憑空想象定位問題的人提個醒,請不要隨意對自己不瞭解的問題定性,因為別人不會把你看做高手,只會對你視而不見。

  2. 在找出jbd2的問題之後,看到一些論壇解決方案說是由於linux核心的bug可以選擇升級系統核心或者修改核心配置項來解決,也許是對的,但是即使能解決這個問題對我來說成本也很大。我希望大家遇到問題時在利用網路資源的同時結合自己的情況進行進一步分析再選擇採用什麼解決方案,適合自己的才是最好的