Linux系统:保证数据安全落盘

  

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

     <强>      Linux      ,输入输出         

  所谓一图胜千言,为了解析清楚这些概念的区别,我特意画了一张图,仔细看,应该可以清晰的看出它们的作用和区别。   
   Linux系统:保证数据安全落盘”>
  <br/>
  这里重点说一下O_DIRECT和O_SYNC,首先要明确的是,O_DIRECT只是说数据不会经过页面缓存(一般用在用户态自己管理缓冲区)而是直接提交给块设备层,但是不会同步等待数据安全写入磁盘之后才返回(比如数据可能还在块层排队或者在磁盘自己的缓存中)。而O_SYNC标志,虽然数据还是会写页面缓存,但是此时会采用写通过的策略,并同步等待数据安全写入磁盘后才会返回。因此如果同时使用O_DIRECT和O_SYNC,则表示数据不会经过页面缓存并同步等待数据安全写入磁盘才返回,当然这样IO的性能会非常低下。
  <br/>
  由于O_DIRECT会绕过页面缓存,因此如果有另一个进程使用普通的方式读文件,有可能会出现数据不一致的现象,这个也需要注意。
  <br/>
  为了做一下辅助说明,此处我贴一下我探讨过程中看过的一些资料。首先是引用开放的系统调用:
  <br/>
  
  http://man7.org/linux/man-pages/man2/open.2.html 
  
  <br/>
  相关参数的说明:
  <br/>
  <img src=Linux系统:保证数据安全落盘