我们都知道,在Linux关机的之前都会要运行一个命令那就是sync,这个命令是同步的意思,那为什么要运行这个?而且之前的数据改变我们已经看见了,为什么还要运行这个命令?要回答这个问题就要说一下Linux在这方面的执行机制。

首先我们要从buffer和cache说起,如下图:

buffer和cache都可以翻译成缓存,但是到底有什么区别呢?

cache:

目的是为了数据重复使用,在一定程度上解决读的效率,这里就是用来存放经常用到的数据,而不用每次都去磁盘上面读取,如果本次操作用到的数据没有,则会到磁盘上去寻找。这样就可以在一定程度上协议快速和慢速设备(比如:CPU和硬盘),另外cache也有换进换出机制,就是把原来经常用到,现在不常用的清除掉,这样就可以有空间放最近访问的数据了,以达到下次访问就直接从cache中读取。

buffer:

为了提高写如磁盘时的效率,其实也是为了协调快慢设备,避免造成把数据都提交到写入磁盘队列造成拥堵,因为内核把数据提交到写入队列不可能不管,它必须要等到有返回值才行。所以buffer的作用是先把数据写入(Linux中的write()函数)到buffer中,然后后台再去根据其他机制,把buffer中的数据提交到队列,最终完整同步到磁盘的过程。

我们知道用户发起的程序都会运行在内存中的用户空间内,这时候数据是放在内存中的,如果我们此时需要保存数据,这时候系统其实是先调用一个write()函数,然后再调用sync()或者fsync()函数(对于任何程序来说只要想把数据写入磁盘其过程都一样,有些也有例外)。

顺便说一句,这也就是为什么有人说Linux比Windows消耗内存的原因。

用户空间:常规进程所在区域,用户发起的,此区域的代码不能直接访问硬件

内核空间:操作系统所在区域,能访问硬件

当调用了write()函数时,该函数一旦返回正常值,我们可能就认为数据已经写入到了磁盘,但实际上,操作系统在实现磁盘文件的IO时,为了保证IO的效率,会在内存中使用一段专门的地址空间,该空间叫做内核空间,而内核空间之内又会有一段是用作IO的数据缓冲区(这个缓冲区就是buffer),write()函数的作用就是把数据写入到内核空间的IO缓冲区中。

内核空间的IO缓冲区也有一定大小,当该缓冲区没有写满时或者没有到一个同步周期时,会持续的把write()函数传递的数据写入到该缓冲区中,而当该缓冲区写满或者到了一个同步周期,则会把该缓冲区的内容提交到输出队列,当需要数据到达队列队首的时候,开始执行真正的磁盘IO操作,把数据写入磁盘(这里虽然用了写入磁盘,但是真正的动作不是移动而是复制,复制完成之后,内核空间的IO缓冲区才会释放该数据占用的空间)。这种方式叫做延迟写入。

所以这就会出现一个问题,当调用了write()函数后并不等于数据真的保存到了磁盘,但是这里又会有一个错觉,就是你再次请求该文件的时候,可以显示你最后一次更新的内容,其实这个内容并不是从磁盘上读取过来的,而是从用户空间的缓冲区读取的。接着刚才提到的问题,如果数据在内核空间的IO缓冲区内,而此时操作系统出现故障、断电等异常情况就会造成数据丢失。

为了解决数据丢失问题,Unix系统提供了sync、fsync和fdatasync三个函数。

函数 功能
sync 函数返回0表示成功,该函数负责把所有内核空间中IO缓冲区内修改过的内容推送到输入队列,然后就返回,它并不等待所有磁盘IO操作完成。所以即使调用了sync函数,也不等于成功保存到磁盘了。
fsync 函数返回0表示成功,与sync不同,它只会对指定文件描述符的单一文件生效,强制与该文件相连的所有修改过的数据传送到磁盘上,并且等待磁盘IO完毕,然后返回。当该函数返回0时,才真正表示成功保存到磁盘。数据库会在调用了write()之后调用fsync()。
fdatasync 它与fsync类似,它只影响文件数据部分,不涉及数据属性,比如inode信息。所以相对于fsync它需要较少的写磁盘操作。

看了上面的内容你就应该明白为什么关机前要运行一下sync命令了。

Linux系统的数据写入机制--延迟写入的更多相关文章

  1. linux 系统中将数据写入文档不能立即保存问题的解决方法

    应用场景: 设备跑的是Linux系统,与PC上位机进行通信,上位机可以给Linux发送设备配置信息,Linux将配置信息写入文件中以备设备断电重启时使用. bug现象: 设备正常运行,设备配置信息为A ...

  2. Linux系统的快速启动机制(内核切换) 【转】

    转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26807463&id=4187846 原文地址:Linux系统的 ...

  3. (转)Linux系统sersync数据实时同步

    Linux系统sersync数据实时同步 原文:http://blog.csdn.net/mingongge/article/details/52985259 前面介绍了以守护进程的方式传输或同步数据 ...

  4. Linux系统捕获数据包流程

    Linux系统捕获数据包流程 为了提高数据包的捕获效率,瓶颈问题是一个需要非常关注的焦点.减少在捕获数据包过程中的瓶颈,就能够提高数据包捕获的整体性能.下面本文将以Linux操作系统为平台,分析捕获数 ...

  5. Linux系统实时数据同步inotify+rsync

    一.inotify简介 inotify是Linux内核的一个功能,它能监控文件系统的变化,比如删除.读.写和卸载等操作.它监控到这些事件的发生后会默认往标准输出打印事件信息.要使用inotify,Li ...

  6. 阿里云Linux系统挂载数据盘

    Linux云服务器数据盘未做分区和格式化,我们可以根据以下步骤进行分区以及格式化操作. 目录 [隐藏]  1 查看数据盘 2 对数据盘进行分区 3 查看新的分区 4 格式化新分区 5 添加分区信息 6 ...

  7. Linux系统SCSI磁盘扫描机制解析及命令实例(转)

    转载请在文首保留原文出处:EMC中文支持论坛 介绍 Linux系统扫描SCSI磁盘有几种方式?Linux新增LUN之后,能否不重启主机就认出设备?如果安装了PowerPath,动态添加/删除LUN的命 ...

  8. Linux系统SCSI磁盘扫描机制解析及命令实例

    介绍Linux系统扫描SCSI磁盘有几种方式?Linux新增LUN之后,能否不重启主机就认出设备?如果安装了PowerPath,动态添加/删除LUN的命令是什么?本文总结了Linux主机对磁盘设备进行 ...

  9. 阿里云里面的Linux 系统挂载数据盘

    转自:http://www.cnblogs.com/adjk/p/5112360.html 适用系统:非IO优化+SSD云盘Linux(Redhat , CentOS,Debian,Ubuntu)实例 ...

随机推荐

  1. Adams命令

    1. FIND_MACRO_FROM_COMMAND(STRING): 通过宏命令找到宏所在位置 2. DEFAULT_GROUND($_topgui.model): 获取默认地面Part 3. DB ...

  2. 手机QQ公众号亿级消息实时群发架构

    编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由孙子荀分享.转载请注明来自高可用架构公众号 ArchNotes.   孙子荀,2009 年在华为从事内核和分布式系统的开发工作:2011 ...

  3. Unity Bolt插件 基本使用

    1.Bolt的安装和配置 导入插件后可以看到 设置命名方式,左侧:普通人,右侧: 程序员 设置变量类型(可以手动添加自己自定义的类型) 然后点击生成,等待bolt编译生成. 2.创建一个流程并使用 如 ...

  4. C#调用Interrop.excel导出Excel文件失败解决方案

    最近操作员反馈系统在导出Excel时失败,有抛出如下异常:系统错误信息:检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件时失 ...

  5. 使用mongo获取文章

    先在命令行中输入mongo,进入mongo,然后 show dbs # 从结果中发现有cmb_demo_23_hacker use cmb_demo_23_hacker db.all_in_one.f ...

  6. vue 学习

    1.安装vue.js 学习链接: https://cn.vuejs.org/v2/guide/ vue官方文档 vscode 软件框架 https://doc.vux.li/zh-CN/ vux文档

  7. codeforces 13 D

    给你500个红点和蓝点,让你找多少点红点构成的三角形里没有蓝点. 巧妙啊!我们考虑一个很远位置的点,不妨设这个为O,然后n^2枚举红点,考虑Oij里面蓝点的个数, 然后 对于 ijk这个三角形,我们可 ...

  8. idea git将多余的代码提交到本地,如何退回。

    场景:代码commit到本地仓库,还没有push到远程仓库,这时要回退代码. 介绍下Reset Head中三种Reset Type类型: 1.Mixed(默认):它回退到某个版本,本地会保留源码,回退 ...

  9. What is volatile?

    What is volatile? 一次偶然的机会(java多线程电梯作业寻求多个进程分享变量的方法),接触到了volatile,因此我查阅了相关的材料,对这部分做了一些了解,在这里和大家分享一下. ...

  10. eclipse中生成的html存在中文乱码问题的解决方法

    最近在做测试报告生成时遇到了个中文乱码的问题,虽然在html创建过程中设置了编码格式htmlReporter.config().setEncoding("UTF-8");但是生成的 ...