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:
開始的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把事務提交完成,才會返回。
另外,當log_start_commit返回0時,fsync就不會等待事務提交完成。到這裡已經基本可以確認第2次fsync的開銷為什麼那麼小了——沒有wait事務提交。
下面驗證這一想法。為了方便除錯,開啟了核心jbd debug日誌。
2.3 測試程式2
從第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的呼叫。
出處:
深入理解F1 score
本部落格的截圖均來自zeya的post essential things you need to know about f1 score by zeya towards data science f1 score的定義 準確率 precision 和召回率 recall 的調和平均 harmonic...
深入理解C語言 深入理解指標
關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...
mysql 索引深入理解 深入理解MySql的索引
為什麼索引能提高查詢速度 先從 mysql的基本儲存結構說起 mysql的基本儲存結構是頁 記錄都存在頁裡邊 各個資料頁可以組成乙個雙向鍊錶每個資料頁中的記錄又可以組成乙個單向鍊錶 每個資料頁都會為儲存在它裡邊兒的記錄生成乙個頁目錄,在通過主鍵查詢某條記錄的時候可以在頁目錄中使用二分法快速定位到對應...