Linux系统:保证数据安全落盘
在很多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的功能吗?本文将试图理解、解释这些概念的作用和区别。
所谓一图胜千言,为了解析清楚这些概念的区别,我特意画了一张图,仔细看,应该可以清晰的看出它们的作用和区别。
这里重点说一下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
相关参数的说明:
以及innodb相关的文档:
https://lwn.net/Articles/457667/
fsync和fdatasync的区别:
http://man7.org/linux/man-pages/man2/fsync.2.html
msync:
http://man7.org/linux/man-pages/man2/msync.2.html
其实还有一种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/3061822
Linux系统:保证数据安全落盘的更多相关文章
- Linux:保证数据安全落盘
背景 在很多IO场景中,我们经常需要确保数据已经安全的写到磁盘上,以便在系统宕机重启之后还能读到这些数据.但是我们都知道,linux系统的IO路径还是很复杂的,分为很多层,每一层都可能会有buffer ...
- Linux/UNIX编程如何保证文件落盘
本文转载自Linux/UNIX编程如何保证文件落盘 导语 我们编写程序write数据到文件中时,其实数据不会立马写入磁盘,而是会经过层层缓存.每层缓存都有自己的刷新时机,每层缓存都刷新后才会写入磁盘. ...
- Java如何保证文件落盘?
本文转载自Java如何保证文件落盘? 导语 在之前的文章Linux/UNIX编程如何保证文件落盘中,我们聊了从应用到操作系统,我们要如何保证文件落盘,来确保掉电等故障不会导致数据丢失.JDK也封装了对 ...
- 在Linux系统下制作系统启动盘(Ubuntu Linux)
在Linux系统下制作系统启动盘有两种方法: 1.用dd命令 2.用Linux自带的图形界面工具 Startup Disk Creator 本教程使用第2种方式,用Linux自带的图形界面工具制作系统 ...
- linux系统创建windows启动盘
平时工作中用到linux的操作命令较多,因此为了方便,就给电脑装了双系统,一般工作的时候,都选择进入linux系统.但是今天有件工作之外的事情需要解决下:创建一个windows启动盘.如果按照往常来说 ...
- 如何实现Kali linux系统下的U盘启动(小白指导)
一.准备工作: 声明:这个“操作”并不会影响你原装的系统,真正的即插即用的哦. (1)4GB的U盘<读写速度比较快的> (2)Kali linux镜像文件 (3)软件Universal-U ...
- Linux系统下面挂载u盘
1.先插好u盘到Linux服务器,然后查看u盘挂载到哪个目录下面. [root@localhost ~]# /sbin/fdisk -l 2.挂载到u目录下面 [root@localhost ~]# ...
- linux系统无法挂载U盘
插上U盘 [ 2407.650440] usb 1-3.3: new high speed USB device number 7 using s5p-ehci [ 2407.887332] usb ...
- 在linux系统中出现u盘问题 的相关解决方法
1.显示unknown filesystem type .exfat 可以通过该方法解决: 安装exfat-fuse: 在终端中以管理员身份运行 sudo apt-get install exfat- ...
随机推荐
- [技术博客] 【vagrant】硬盘扩容
同样,这也是少昂早年走过的坑,这里直接贴出少昂个人博客链接:https://www.cnblogs.com/HansBug/p/9447020.html PS:有一位经验丰富的后端大佬坐镇指挥是多么幸 ...
- 冰多多团队-第十次Scrum例会
冰多多团队-alpha第十次Scrum会议 工作情况 团队成员 已完成任务 待完成任务 牛雅哲 修复了Iatdemo语音接口的bug,整个demo pipeline跑通 为词库设计更多的扩展模块和扩展 ...
- 在Asp.Net Core 3.0中如何使用 Newtonsoft.Json 库序列化数据
在.Net Core 3.0中 内置了一套Json序列化/反序列化方案,默认可以不再依赖,不再支持 Newtonsoft.Json. 但是.NET Core 3.0 System.Text.Jso ...
- 关于最新版本的flutter在安卓打包的问题解决方法
1.集成友盟push提示androidx版本号不一致,需在gradle文件中手动选择即可,如下 buildscript { repositories { google() jcenter() mave ...
- 【基础】Qt SCXML Calculator QML Example
Qt SCXML Calculator QML Example 这个系统自带的例子原本主要是用来说明SCXML机制的,但是由于计算器的经典和简洁,我认为用来练习QML非常合适,原本的例子还有一些问题, ...
- WebGL学习笔记(十六):遮罩
这里总结下几种WebGL中实现遮罩的方法. 模板缓冲 模板缓冲可以实现渲染剔除,但是我们之前的学习里,剔除范围是基于上一次渲染的结果,且上一次的渲染也会进行显示,这样的话并不适合用来实现遮罩. 我们想 ...
- docker入门-基本概念(一)
Docker是什么 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker的应用场景 Web 应用的自动化打包和发布. 自动化测试和持续集成.发 ...
- github 被强了!太丧心病狂了!
github 不强了! github 不能访问了! github 打不开了! github 被封了... - ping 都 ping 不通, 本地 ping 不通, 服务器 ping 不通. - 本地 ...
- 两分钟观看 nodejs、 iojs、 npmjs 之间的狗血剧情
开门大吉,欢迎光临.这是 乐玩nodejs npm工具库 微信公众号的第一篇文章,那就先来说说 nodejs/npm 的小秘密,话不多说,赶快开始: 通过一个时间线简要描述下 2008 年 V8 引擎 ...
- jzy3D从入门到弃坑_2使用jzy3D0.9画2D散点图
jzy3D从入门到弃坑_2 使用jzy3D0.9画2D散点图 觉得有用的话,欢迎一起讨论相互学习~Follow Me 在上一节中安装jzy3D 0.9版本并且运行了3D的例子 https://blog ...