Linux:保证数据安全落盘

背景html

在不少IO场景中,咱们常常须要确保数据已经安全的写到磁盘上,以便在系统宕机重启以后还能读到这些数据。可是咱们都知道,linux系统的IO路径仍是很复杂的,分为不少层,每一层均可能会有buffer来加速IO读写。同时,用户态的应用程序和库函数也可能拥有本身的buffer,这又给IO路径增长了一些复杂性。可见,要想保证数据安全的写到磁盘上,并非简单调一个write/fwrite就能够搞定的。
那么要怎么作呢?不少人会想到不少办法,好比:fflush()、fsync()、fdatasync()、sync()、open()使用O_DIRECT或O_SYNC标志等。嗯,这些手段(或者某些组合)的确能够保证数据安全的持久化,那么它们之间有什么区别呢?fflush()和fsync()有啥区别?O_DIRECT是啥意思,它能够保证数据安全的持久化吗?O_DIRECT和O_SYNC区别什么?O_SYNC和fsync()呢?fsync能完成msync的功能吗?本文将试图理解、解释这些概念的做用和区别。linux

Linux IO

所谓一图胜千言,为了解析清楚这些概念的区别,我特地画了一张图,仔细看,应该能够清晰的看出它们的做用和区别。
Linux:保证数据安全落盘Linux:保证数据安全落盘
这里重点说一下O_DIRECT和O_SYNC,首先要明确的是,O_DIRECT只是说数据不会通过page cache(通常用在用户态本身管理buffer)而是直接提交给块设备层,可是不会同步等待数据安全写入磁盘以后才返回(好比数据可能还在块层排队或者在磁盘本身的cache中)。而O_SYNC标志,虽然数据仍是会写page cache,可是此时会采用write through的策略,并同步等待数据安全写入磁盘后才会返回。所以若是同时使用O_DIRECT和O_SYNC,则表示数据不会通过page cache并同步等待数据安全写入磁盘才返回,固然这样IO的性能会很是低下。
因为O_DIRECT会bypass page cache,所以若是有另外一个进程使用普通的方式读文件,有可能会出现数据不一致的现象,这个也须要注意。
为了作一下辅助说明,此处我贴一下我探讨过程当中看过的一些资料。首先是引用open系统调用:
http://man7.org/linux/man-pages/man2/open.2.html 
相关参数的说明:
Linux:保证数据安全落盘Linux:保证数据安全落盘
以及innodb相关的文档:
https://lwn.net/Articles/457667/
Linux:保证数据安全落盘Linux:保证数据安全落盘
fsync和fdatasync的区别:
http://man7.org/linux/man-pages/man2/fsync.2.html
Linux:保证数据安全落盘Linux:保证数据安全落盘
msync:
http://man7.org/linux/man-pages/man2/msync.2.html
Linux:保证数据安全落盘Linux:保证数据安全落盘安全

DAX

其实还有一种IO模式,就是DAX(Direct Access ),是否是看上去和O_DIRECT很像。这种模式须要filesystem和block driver都支持才能够,通常主要用在non volatile memory上,本质上也是绕过page cache直接操做设备。DAX本文先不作深刻探讨,后面我会本身写一个支持DAX模式的ramdisk块设备驱动,而后格式化为ext4文件系统并-o dax模式挂载,再来详细研究DAX的IO路径。
最后附上Linux在常见场景下的io路径跟踪:
https://my.oschina.net/fileoptions/blog/3061822async

相关文章
相关标签/搜索