最近在測試種發現程式裡調用fsync刷檔案到磁盤時,開銷隻有幾百微秒,于是對fsync相關機制進行了一番調查。
磁盤(或RAID卡)自身通常會有硬體緩存機制,對于寫操作,有write back和write through兩種機制,前者将資料寫至緩存就會傳回,而後者則會将資料寫到磁盤媒體上。當使用write back機制時,fsync刷的檔案資料可能隻是寫到磁盤緩存就傳回了,導緻從應用看來,寫資料到磁盤的開銷很小(實際上并未執行磁盤寫操作);是以,使用write back機制時,即使上層應用顯式fsync成功,資料也是可能丢失的,比如緩存裡的資料還未刷到磁盤時掉電了,有些儲存設備會使用備用電池(BBU,Battery backup unit)來避免掉電時緩存資料丢失。
如果要保證fsync調用成功後,資料一定持久化到磁盤,則要使用核心的write barrier機制。該機制通過在IO操作之前和之後顯式重新整理儲存設備的緩存來達到目的,在檔案系統mount的時候可以指定是否開啟barrier機制,ext4預設啟用barrier機制。
對于記憶體映射(mmap)的檔案資料,msync的功能與fsync類似,将記憶體映射資料刷到磁盤,msync使用時有3個标志。
MS_SYNC,資料同步刷到磁盤後傳回(可能隻是寫到磁盤緩存)
MS_ASYNC, 對于更新的檔案資料會送出IO操作到底層,但不會等IO操作執行完成,而是立即傳回
MS_INVALIDATE,更新檔案對應的其它映射資料(如記憶體區域M1、M2都映射了檔案F的資料,如果在msync M1的時候指定了該标記,則M2記憶體區域裡的資料也會被更新)。
要想映射記憶體msync後被持久化到磁盤,需要使用MS_SYNC标記;而msync調用後資料是否一定持久化,則要看儲存設備使用的緩存機制以及核心write barrier是否啟用。
本文轉自 jiu~ 部落格園部落格,原文連結:http://www.cnblogs.com/jiu0821/p/7682015.html,如需轉載請自行聯系原作者