【珍藏】linux 同步IO: sync、fsync与fdatasync
传统的UNIX实现在内核中设有缓冲区高速缓存或页面高速缓存,大多数磁盘I/O都通过缓冲进行。当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列,而是等待其写满或者当内核需要重用该缓冲区以便存放其他磁盘块数据时,再将该缓冲排入输出队列,然后待其到达队首时,才进行实际的I/O操作。这种输出方式被称为延迟写(delayed
write)(Bach [1986]第3章详细讨论了缓冲区高速缓存)。
延迟写减少了磁盘读写次数,但是却降低了文件内容的更新速度,使得欲写到文件中的数据在一段时间内并没有写到磁盘上。当系统发生故障时,这种延迟可能造成文件更新内容的丢失。为了保证磁盘上实际文件系统与缓冲区高速缓存中内容的一致性,UNIX系统提供了sync、fsync和fdatasync三个函数。
(1) sync函数只是将所有修改过的块缓冲区排入写队列,然后就返回,它并不等待实际写磁盘操作结束。通常称为update的系统守护进程会周期性地(一般每隔30秒)调用sync函数。这就保证了定期冲洗内核的块缓冲区。命令sync(1)也调用sync函数。
(2) fsync函数只对由文件描述符filedes指定的单一文件起作用,并且等待写磁盘操作结束,然后返回。fsync可用于数据库这样的应用程序,这种应用程序需要确保将修改过的块立即写到磁盘上。
(3) fdatasync函数类似于fsync,但它只影响文件的数据部分。而除数据外,fsync还会同步更新文件的属性。
<fsync不但更新数据,还会更新元数据——文件的属性,但fdatasync仅更新数据>
对于提供事务支持的数据库,在事务提交时,都要确保事务日志(包含该事务所有的修改操作以及一个提交记录)完全写到硬盘上,才认定事务提交成功并返回给应用层。
一个简单的问题:在linux/unix操作系统上,怎样保证对文件的更新内容成功持久化到硬盘?
1. write不够,需要fsync
1 #include <unistd.h>
2 int fsync(int fd);
1 #incude <sys/mman.h>
2 int msync(void *addr, size_t length, int flags)
msync需要指定同步的地址区间,如此细粒度的控制似乎比fsync更加高效(因为应用程序通常知道自己的脏页位置),但实际上(Linux)kernel中有着十分高效的数据结构,能够很快地找出文件的脏页,使得fsync只会同步文件的修改内容。
2. fsync性能问题,与fdatasync
& st_mtime等等),因为文件的数据和metadata通常存在硬盘的不同地方,因此fsync至少需要两次IO写操作,fsync的man page这样说:
"Unfortunately fsync() will alwaysalways
initialize two write operations: one for the newly written data and another one in order to update the modification time stored
in the inode. If the modification time is not a part of the transaction concept fdatasync() can be used to avoid unnecessary inode disk write operations."
多余的一次IO操作,有多么昂贵呢?根据Wikipedia的数据,当前硬盘驱动的平均寻道时间(Average
seek time)大约是3~15ms,7200RPM硬盘的平均旋转延迟(Average rotational latency)大约为4ms,因此一次IO操作的耗时大约为10ms左右。这个数字意味着什么?下文还会提到。
Posix同样定义了fdatasync,放宽了同步的语义以提高性能:
1 #include <unistd.h>
2 int fdatasync(int fd);
page中的解释:
"fdatasync does not flush modified metadata unless that metadata is needed in order to allow a subsequent data retrieval to be corretly handled."
3. 使用fdatasync优化日志同步
在Berkeley DB下,如果开启了AUTO_COMMIT(所有独立的写操作自动具有事务语义)并使用默认的同步级别(日志完全同步到硬盘才返回),写一条记录的耗时大约为5~10ms级别,基本和一次IO操作(10ms)的耗时相同。
1.每个log文件固定为10MB大小,从1开始编号,名称格式为“log.%010d"2.每次log文件创建时,先写文件的最后1个page,将log文件扩展为10MB大小3.向log文件中追加记录时,由于文件的尺寸不发生变化,使用fdatasync可以大大优化写log的效率4.如果一个log文件写满了,则新建一个log文件,也只有一次同步metadata的开销
【珍藏】linux 同步IO: sync、fsync与fdatasync的更多相关文章
- Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式
Linux就这个范儿 第15章 七种武器 linux 同步IO: sync.fsync与fdatasync Linux中的内存大页面huge page/large page David Cut ...
- linux 同步IO: sync、fsync与fdatasync
[linux 同步IO: sync.fsync与fdatasync] 传统的UNIX实现在内核中设有缓冲区高速缓存或页面高速缓存,大多数磁盘I/O都通过缓冲进行.当将数据写入文件时,内核通常先将该数据 ...
- linux 同步IO: sync msync、fsync、fdatasync与 fflush
最近阅读leveldb源码,作为一个保证可靠性的kv数据库其数据与磁盘的交互可谓是极其关键,其中涉及到了不少内存和磁盘同步的操作和策略.为了加深理解,从网上整理了linux池畔同步IO相关的函数,这里 ...
- linux 同步IO: sync、fsync与fdatasync、sys_sync【转】
本文转自:http://blog.csdn.net/cywosp/article/details/8767327 和 http://www.2cto.com/os/201204/126687.html ...
- Linux系统调用---同步IO: sync、fsync与fdatasync【转】
转自:http://blog.csdn.net/cywosp/article/details/8767327 [-] 1 write不够需要fsync 2 fsync的性能问题与fdatasync ...
- 同步内核缓冲区sync、fsync和fdatasync函数
转自http://www.2cto.com/os/201409/339460.html 同步内核缓冲区 1.缓冲区简介 人生三大错觉之一:在调用函数write()时,我们认为该函数一旦返回,数据便已经 ...
- 同步内核缓冲区 sync、fsync和fdatasync函数
同步内核缓冲区 1.缓冲区简单介绍 人生三大错觉之中的一个:在调用函数write()时,我们觉得该函数一旦返回,数据便已经写到了文件里.可是这样的概念仅仅是宏观上的.实际上.操作系统实现某些文件I/O ...
- 【Linux】文件IO --- sync、fsync、fdatesync
在使用write函数向文件中写入数据的时候,并不是在调用了函数以后就直接把数据写入磁盘:操作系统在内核中设置了一块专门的缓冲区,数据会先被写入到内核的缓冲区中,等到缓冲区满了或者系统需要重新利用缓冲区 ...
- sync fsync fdatasync ---systemtap跟踪
aa.stp: probe kernel .function ( "sys_sync" ) { printf ( "probfunc:%s fun:%s\n", ...
随机推荐
- 微信企业号接收消息(使用SpringMVC)
微信企业号接收消息(使用SpringMVC) 微信企业号接收消息(使用SpringMVC) 将应用设置在回调模式时,企业可以通过回调URL接收员工回复的消息,以及员工关注.点击菜单.上报地理位置等事件 ...
- [编织消息框架][设计协议]opCode
OpCode的全称 OpCode(Operation Code) 操作码的意思. OpCode 有几种域组成,不同领域格式组成不同 1.指令号 2.数据范围 3.数据内容 如 {code}{addr ...
- 帝国CMS万能标签的使用
标签名称: 带模板的信息调用标签[万能标签] [ecmsinfo]栏目ID/专题ID,显示条数,标题截取数,是否显示栏目名,操作类型,标签模板ID,只显示有标题图片[/ecmsinfo] 说明:e ...
- (16)IO流之输入字节流FileInputStream和输出字节流FielOutputStream
IO流技术解决的问题:设备与设备之间的传输问题,内存-->硬盘,硬盘-->内存,等等 IO流技术 如果按照数据的流向划分可以划分为:输入流和输出流 输入输出的标准是以程序为参考物的,如果流 ...
- linux vi hjkl由来
很远原因来自历史 I was reading about vim the other day and found out why it used hjkl keys as arrow keys. Wh ...
- 走入PHP-类与对象
PHP中用class来定义类,用new实例化对象,用extends继承类,不过只能单继承,属性和方法有public.private和protected做访问控制,默认为public,在类里定义常量不需 ...
- 深入理解ajax系列第九篇——jQuery中的ajax
前面的话 jQuery提供了一些日常开发中需要的快捷操作,例如load.ajax.get和post等,使用jQuery开发ajax将变得极其简单.这样开发人员就可以将程序开发集中在业务和用户体验上,而 ...
- 分块编码(Transfer-Encoding: chunked)
参考链接: HTTP 协议中的 Transfer-Encoding 分块传输编码 一.背景: 持续连接的问题:对于非持续连接,浏览器可以通过连接是否关闭来界定请求或响应实体的边界:而对于持续连接,这种 ...
- 平时自己项目中用到的CSS
outline 当选中input元素的时候会出现状态线, outline设置成none就没了 input{ outline:none; } contentditable 设置元素内的文本是否可编辑 ...
- formvalidation表单验证
官方文档:http://formvalidation.io var $formEntityProfileSearch = $("form[name=entityProfileSearch]& ...