面试实录-写文件的时候,进程如果宕机了,数据是否会丢失?

面试官问:

写文件的时候,进程如果宕机了,数据是否会丢失?


前置知识:

在应用程序中会有一些日志写到磁盘里面,如果进程宕机了,我们之前数据是否会丢失?

这里主要考察的是写文件流程是否清晰。

大家在写文件的时候会用到一些库:

第一个就是stdio函数库;

另外一个就是最原生的open、write去写接口。

这两种写的方式有什么不同?

如果我们使用的是stdio函数库:

里面会有这么几个接口fopen、fwrte、fflush 。最后,如果我们需要把缓冲池里面的数据刷到磁盘里面,那我们还会调用fsync,有这么几个流程。写完之后,我们调用fclose。这么几个接口。

还有就是原生的。原生就是直接open  打开一个fd,打开之后write,调用fsync把数据刷到磁盘里面,最后close

有什么不同呢?

  • 前者的函数参数 是file 开头的数据流

  • 后者的是fd相关的

面试实录-写文件的时候,进程如果宕机了,数据是否会丢失?_第1张图片

                                                 stdio数据库写文件流程图

首先fopen打开一个文件,文件是file类型,然后把数据发write写到用户态的这个buf里面,调用fflush,把数据刷到page cache,然后再调用fsync,把数据刷到磁盘里面,这是一个完整的流程。

需要注意的是,如果我们没有调用这个fflush,那数据就是在用户态,此时数据就可能会丢失。那fclose也是同样的作用,如果没有调用fflush,而是调用的fclose,那数据同样是可以刷到我们的page cache的。fflush本质上就是把系统调用的write封装了一层而已。

第二种接口是怎么写数据的呢

Open打开一个具体文件,返回的是一个fd。然后在通过write系统调用,把用户态的数据刷到page cache再用fsync把数据刷到磁盘里面。

回归问题本身,数据是否丢失?

需要分情况讨论(如果是使用的stdio数据库):

1.如果没有调用fflush、fclose。那数据就还在用户态缓冲区里面,进程宕机了,那么进程所对应的数据就丢失了,所以肯定会丢失。

2.如果数据调用了fflush、fclose,那数据是在page cache,但机器断电了,数据还是会丢失。

扩展:

1.如果我们使用了直接文件IO open(o_redict),那文件是不会丢失的,会直接到磁盘。

2.Fflushfsync的区别在于:fflush是把数据从用户态缓冲区刷到page cache,而fsync是把数据从page cache刷到磁盘。

3.Fsyncfdatasync有什么区别?Fdatasync是把fd所对应的数据直接刷到磁盘里面。Fsync还会把文件属性刷到磁盘里面。

 原文转载于:公众号

你可能感兴趣的:(数据库)