1 介紹
資料庫系統從誕生那天開始,就面對一個很棘手的問題,fsync的效能問題。組提交(group commit)就是為了解決fsync的問題。最近,遇到一個業務反映MySQL建立分割槽表很慢,仔細分析了一下,發現InnoDB在建立表的時候有很多fsync——每個檔案會有4個fsync的呼叫。當然,並不每個fsync的開銷都很大。
這裡引出幾個問題:
(1)問題1:為什麼fsync開銷相對都比較大?它到底做了什麼?
(2)問題2:細心的人可以發現,第一次open資料檔案後,第二次fsync的時間遠遠小於第1次呼叫fsync的時間,為什麼?
(3)問題3:能否最佳化fsync?
來著這些疑問,一起來了解一下fsync。
2 原因分析
我們先透過一個測試程式來學習一下fsync在塊層的基本流程。
2.1 測試程式1
Write page 0 Sleep 5 Fsync |
用blktrace跟蹤結果如下:
上半部紅色框內為pwrite在塊層的流程,下半部黃色框內為fsync在塊層流程,中間剛好相差5秒。
4722712為測試檔案的第1個block對應的扇區號,590339(block號) * 8=4722712(扇區號)。
無論是pwrite,還是fsync,主要的開銷都發生IO請求提交給驅動和IO完成之間,也就是說開自裝置驅動。差不多佔了整個系統呼叫的1/2的開銷。
另外,可以看到呼叫fsync時,發生了3次塊層IO,起始扇區分別是19240、19248和19256,物理上3個連續的塊。實際上這3個塊為核心執行緒kjournald寫的日誌,分別描述塊(2405)、資料塊(2406)和提交塊(2407)。為了驗證,不妨看一下這三個塊的實際資料。
塊2405:
#define JFS_MAGIC_NUMBER 0xc03b3998U #define JFS_DESCRIPTOR_BLOCK 1 #define JFS_COMMIT_BLOCK 2 |
開始的4個位元組為JFS_MAGIC_NUMBER,然後是block type:JFS_DESCRIPTOR_BLOCK。
塊2407:
的確是提交塊。
2.2 fsync的實現
既然fsync的開銷很大,就來看看程式碼吧。
函式ext3_sync_file:
函式log_start_commit負責喚醒kjounald核心執行緒,log_wait_commit等待jbd事務提交完成。
從程式碼來看,fsync的主要開銷在於呼叫log_wait_commit後的等待。也就是說fsync要等待kjournald把事務提交完成,才會返回。
到這裡,我們已經知道了fsync開銷的主要來源:(1)硬體驅動層的開銷;(2)ext3寫日誌。
另外,當log_start_commit返回0時,fsync就不會等待事務提交完成。到這裡已經基本可以確認第2次fsync的開銷為什麼那麼小了——沒有wait事務提交。
下面驗證這一想法。為了方便除錯,開啟了核心jbd debug日誌。
2.3 測試程式2
Write page 0 Fsync Write page 0 Fsync Write page 1 Fsync Write page 2 Fsync |
從第2個紅框的日誌來看,第2次fsync時,的確是沒有wait的,所以開銷這麼小,而其它3次fsync都呼叫了log_wait_commit函式。
問題4:第2次fsync為什麼不會呼叫log_wait_commit?
因為掛載檔案系統的時候,data=writeback,即寫資料本身不會寫jbd日誌。第2次pwrite沒有引起檔案擴充套件,只會修改ext3 inode的i_mtime,而i_mtime只精確到second,也就是說第2次pwrite不會引起inode資訊改變,所以,不會生成jbd日誌,也就不需要等待事務提交完成。
下面驗證一下該想法。
2.4 測試程式3
Write page 0 Fsync Sleep 1 second Write page 0 Fsync Write page 1 Fsync Write page 2 Fsync |
在第2次pwrite之前,sleep 1秒鐘,保證ext3 inode的i_mtime修改。
想法被證實了,第2次fsync的時間回到正常水平。
可以看到,第2次fsync呼叫提交了新的事務,並呼叫了log_wait_commit等待事務完成。
3 最佳化
如何最佳化fsync?是個難題。
(1)系統減少對fsync的呼叫。
(2)ext3日誌放在更快的儲存介質,參考http://insights.oetiker.ch/linux/external-journal-on-ssd/
作者:YY哥
出處:http://www.cnblogs.com/hustcat/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。