當前位置:
首頁 > 知識 > sync/fsync/fdatasync的簡單比較

sync/fsync/fdatasync的簡單比較

之前在研究MySQL的一個參數innodb_flush_method時,就涉及到了fsync/fdatasync這些庫函數(什麼是庫函數?它與系統調用的區別在哪?參見這裡)。接下來就簡單的分析一下sync/fsync/fdatasync的區別。

sync():int sync( void )這就是它的原型,A call to this function will not return as long as there is data which has not been written to the device,sync()同步寫,沒有寫到物理設備就不會返回,但是現實中並不是這樣的。在kernel的手冊上有解釋:BUGS部分(linux中用man查看命令的時候不是都有一個BUGS部分么,就是指的那個)According to the standard specification (e.g., POSIX.1-2001), sync() schedules the writes, but may return before the actual writing is done. However, since version 1.3.20 Linux does actually wait. (This still does not guarantee data integrity: modern disks have large caches.)也就是sync()負責將這些寫物理設備的請求放入寫隊列,但是不一定寫真正被完成了。

fsync(int fd):The fsync function can be used to make sure all data associated with the open file fildes is written to the device associated with the descriptor。fsync()負責將一個文件描述符(什麼是文件描述符,它是unix、類unix系統打開文件的一種方式,應該相當於打開文件的一個句柄一樣)打開的文件寫到物理設備,而且是真正的同步寫,沒有寫完成就不會返回,而且寫的時候講文件本身的一些元數據都會更新到物理設備上去,比如atime,mtime等等。

fdatasync(int fd):When a call to the fdatasync function returns, it is ensured that all of the file data is written to the device。它只保證開打文件的數據全部被寫到物理設備上,但是一些元數據並不是一定的,這也是它與fsync的區別。

這三個庫函數都簡單的介紹完,那麼為什麼需要它們三個呢?最簡單的說是從應用的需求來考慮的,sync是全局的,對整個系統都flush,fsync值針對單個文件,fdatasync當初設計是考慮到有特殊的時候一些基本的元數據比如atime,mtime這些不會對以後讀取造成不一致性,因此少了這些元數據的同步可能會在性能上有提升(但fsync和fdatasync兩者的性能差別有多大?這個不知道有誰測過沒)。所以說三者是根據不同的需求而定的。

接下來談談flush dirty page,也就是前面說的同步寫(沒寫完的話阻塞後面,直到寫完才返回)。為什麼是刷臟頁?臟頁表示緩存中的頁(一般也就是內存中)也物理設備上的頁處於不一致,不一致是由於在內存中被修改了。所以為了持久化這種內存中的修改,需要flush到物理設備上。根據我的理解,一般來說緩存分成這幾種:1>應用程序自己帶了緩存,比如InnoDB的buffer pool;2>os層面上的緩存 ;3>磁碟設備自己的緩存,比如raid卡一般都管理著自己的緩存;4>磁碟本身或許會有一點點緩存(這個不確定,自己猜想的,這個即使有估計也是極小的)。好了,那麼大部分的時候我們說的flush dirty page都是指從應用程序的緩存->os的緩存->物理設備,如果物理設備沒有緩存的話,此時也就相當於持久化成功,但是像磁碟做了raid,raid卡有緩存的話,實際上還沒真正持久化成功,因為此時還只到了raid卡的緩存,沒到物理設備,但是由於raid卡一般都帶有備用電池,所以即使此時斷電也不會造成數據丟失。

剛才說了很多時候應用自己也有緩存機制,那麼你是否想過此時與os的緩存有重複呢?答案是:會的。剛才說了我是通過研究MySQL的一個參數innodb_flush_method注意這些的,innodb_flush_method表示flush策略,MySQL提供了fdatasync/O_DSYNC/O_DIRECT這三個選項,默認是fdatasync(詳情可參看博文)我這裡主要說明為什麼會提供選項:O_DIRECT。這個選項告訴os,InnoDB在讀寫數據的時候都不經過os的緩存,因為剛才說過InnoDB會維護自己的緩存buffer pool,如果還使用os的緩存那麼兩者就會有一定的重複。在前面參考的文章裡面說O_DIRECT對大量隨即讀寫有效率提升,順序讀寫則會下降。所以根據自己的需求來定,不過如果你的MySQL用在是OLTP上,基本上選擇O_DIRECT沒錯。

sync/fsync/fdatasync的簡單比較

打開今日頭條,查看更多圖片
喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

sprintboot+mybatis踩坑:查詢不到數據list「null」——支持駝峰配置
linux 手工釋放內存 高內存 內存回收 方法思路

TAG:程序員小新人學習 |