我们都知道,在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. C++ 使用 curl 进行 http 请求(GET、POST、Download)的封装

    修改自网路 CommonTools.h /* * CommonTools.h * * Created on: 2018年8月2日 * Author: didi */ #include <iost ...

  2. Java下载文件的几种方式

    转发自博客园Sunny的文章 1.以流的方式下载 public HttpServletResponse download(String path, HttpServletResponse respon ...

  3. KMP性质小结

    跪拜_Blackjack_神犇

  4. 如何在浏览器中输入(myeclipse创建的项目的)地址访问JSP页面

    如何在浏览器中输入(myeclipse创建的项目的)地址访问JSP页面 可以在Tomcat项目里面查看你的JSP页面在哪里,具体的路径为: tomcat--work--localhost--项目名称, ...

  5. angular.uppercase()

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. Go语言基础之接口

    Go语言基础之接口 接口(interface)定义了一个对象的行为规范,只定义规范不实现,由具体的对象来实现规范的细节. 接口 接口介绍 在Go语言中接口(interface)是一种类型,一种抽象的类 ...

  7. easyui-combotree选中指定的值

    选中根节点: //station_id为combotree控件id var station = $('#station_id').combotree('tree').tree('getRoots'); ...

  8. 简单工厂模式demo

    1. 简单工厂模式 domain的接口 public interface Color{ public void display(); } red public Class Red implements ...

  9. Hadoop 集群安装(主节点安装)

    1.下载安装包及测试文档 切换目录到/tmp view plain copy cd /tmp 下载Hadoop安装包 view plain copy wget http://192.168.1.100 ...

  10. Spring Cloud 微服务架构的五脏六腑,统统晒一晒!

    Spring Cloud 是一个基于 Spring Boot 实现的微服务框架,它包含了实现微服务架构所需的各种组件. 注:Spring Boot 简单理解就是简化 Spring 项目的搭建.配置.组 ...