vfs_fsync[通俗易懂]

vfs_fsync[通俗易懂]在Linux系统中,对文件系统上文件的读写一般是通过页缓存(pagecache)进行的(DirectIO除外),这样设计的可以延时磁盘IO的操作,从而可以减少磁盘读写的次数,提升IO性能。但是性能和可靠性在一定程度上往往是矛盾的,虽然内核中设计有一个工作队列执行赃页回写同磁盘文件进行同步,但是在一些极端的情况下还是免不了掉电数据丢失。因此内核提供了sync、fsync、fdatasync和msync系统调用用于同步,其中sync会同步整个系统下的所有文件系统以及块设备,而fsync和fdatasync只针

大家好,又见面了,我是你们的朋友全栈君。

在Linux系统中,对文件系统上文件的读写一般是通过页缓存(page cache)进行的(DirectIO除外),这样设计的可以延时磁盘IO的操作,从而可以减少磁盘读写的次数,提升IO性能。但是性能和可靠性在一定程度上往往是矛盾的,虽然内核中设计有一个工作队列执行赃页回写同磁盘文件进行同步,但是在一些极端的情况下还是免不了掉电数据丢失。因此内核提供了sync、fsync、fdatasync和msync系统调用用于同步,其中sync会同步整个系统下的所有文件系统以及块设备,而fsync和fdatasync只针对单独的文件进行同步,msync用于同步经过mmap的文件。使用这些系统API,用户可以在写完一些重要文件之后,立即执行将新写入的数据回写到磁盘,尽可能的降低数据丢失的概率。本文将介绍fsync和fdatasync的功能和区别,并以Ext4文件系统为例,分析它们是如何将数据同步到磁盘中的。

内核版本:Linux 4.10.1
内核文件:fs/sync.c、fs/ext4/fsync.c、fs/ext4/inode.c、mm/filemap.c

1、概述
当用户在写一个文件时,若在open时没有设置O_SYNC和O_DIRECT,那么新write的数据内容将会暂时保存在页缓存(page cache)中,对应的页成为赃页(dirty page),这些数据并不会立即写回磁盘中。同时内核中设计有一个等待队列bdi_wq以及一些writeback worker,它们在达到一定的条件之后(延迟时间到期(默认5s)、系统内存不足、赃页超过阈值等)就会被唤醒执行赃页(dirty page)的回写操作,文件中新写入的数据在此时才能够写回磁盘。虽然从write操作到writeback之间的窗口时间(Ext4默认启用delay
 alloc特性,该时间延长到了30s)较短,若在此期间设备掉电或者系统奔溃,那用户的数据将会丢失。因此,对于单个文件来说,如果需要提高可靠性,可以在写入后调用fsync和fdatasync来实现文件(数据)的同步。
fsync系统调用会同步fd表示文件的所有数据,包括数据和元数据,它会一直阻塞等待直到回写结束。fdatasync同fsync类似,但是它不会回写被修改的元数据,除非对于一些对于数据完整性检索有关的场景。例如,若仅是文件的最后一次访问时间(st_atime)或最后一次修改时间(st_mtime)发生变化是不需要同步元数据的,因为它不会影响文件数据块的检索,若是文件的大小改变了(st_isize)则显然是需要同步元数据的,若不同步则可能导致系统崩溃后无法检索修改的数据。鉴于fdatasync的以上区别,可以看出应用程序对一些无需回写文件元数据的场景使用fdatasync可以提升性能。
需要注意,如果物理磁盘的write cache被使能,那么fsync和fdatasync将不能保证回写的数据被完整的写入到磁盘存储介质中(数据可能依然保存在磁盘的cache中没有写入介质),因此可能会出现明明调用了fsync系统调用但是数据在掉电后依然丢失了或者出现文件系统不一致的情况。
最后,关于fsync和fdatasync的详细描述可以参考fsync的manual page。
————————————————
版权声明:本文为CSDN博主「luckyapple1028」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/luckyapple1028/article/details/61413724

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/139547.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • oracle数据库sequence的作用_oracle dataguard

    oracle数据库sequence的作用_oracle dataguardsequence概念及作用sequence是用来在多用户环境下产生唯一整数的数据库对象。序列产生器顺序生成数字,它可用于自动生成主键值,并能协调多行或者多表的主键操作。没有sequence,顺序的值只能靠编写程序来生成。先找出最近产生的值然后自增长。这种方法要求一个事务级别的锁,这将导致在多用户并发操作的环境下,必须有人等待下一个主键值的产生。而且此方法很容易产生主键冲突的错误,如下图:如上

    2022年10月18日
    2
  • 常用的安全渗透测试工具(渗透测试工具)

    应用程序安全性并不新鲜,但它在需求、复杂性和深度方面正迅速增长。随着网络犯罪自疫情爆发以来增长了近600%,越来越多的SaaS企业开始争相保护他们的应用程序。即使那些运行最新端点保护的系统也面临重大漏洞。然而随之而来的一个问题是:即便采取了这些安全防护措施,能保护自己不会受到网络攻击吗?答案在于应用程序安全测试解决方案,该解决方案可以主动测试您的代码是否存在错误、关键漏洞和需要全面改进的领域。接下来是常见几种测试。 渗透测试 部署自动化工具,如SAST、DAST、RAST和IAST

    2022年4月16日
    62
  • pycharmpip不是内部或外部命令,也不是可运行程序_pip安装的包pycharm识别不了

    pycharmpip不是内部或外部命令,也不是可运行程序_pip安装的包pycharm识别不了解决pip不是内部或外部命令问题

    2022年8月29日
    4
  • java菜鸟教程+视频笔记

    java菜鸟教程+视频笔记1、java中局部变量是在栈上分配的;2、数组是储存在堆上的对象,可以保存多个同类型变量;3、在Java语言中,所有的变量在使用前必须声明。4、局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。5、内置类型有默认值,引用对象的默认值是null;6、非静态实例变量、非静态方法是通过对象实例进行调用的,不能直接从静态方法中调用;比如java源文件中main方法中不可以直接调用非静态…

    2022年6月14日
    28
  • fleck 客户端_关于C使用Fleck 的websocket问题

    fleck 客户端_关于C使用Fleck 的websocket问题该楼层疑似违规已被系统折叠隐藏此楼查看此楼先上代码 FleckLog Level LogLevel Debug allSockets newList Newsocket newWebSocket ws 127 0 0 1 ctrlPort Newsocket Start socket gt socket OnOpen gt G

    2025年10月30日
    4
  • 利用matlab画三维图像_使用变身卡进行擂台切磋

    利用matlab画三维图像_使用变身卡进行擂台切磋使用MATLAB进行三维图像绘制

    2022年10月11日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号