如何知道何时将数据写入磁盘?

时间:2016-03-03 09:37:03

标签: linux file-io io

我们希望通过检测Linux系统上的read()和write()例程来测量应用程序的I / O时间。但是,对write()的调用返回非常快。根据我的OS手册页写(man 2 write):

  

备注          从write()成功返回并不能保证数据已提交到磁盘。事实上,在一些越野车上   实现,它甚至不保证空间   顺利          已为数据保留。唯一可以确定的方法是在写完所有数据后调用fsync(2)。

     

Linux手册,截至2013-01-27

所以我们理解write()调用会启动异步调用,在某些时候会将数据刷新到磁盘。

所以问题是,有没有办法知道数据(即使它已被分组用于缓存目的)何时被实际写入磁盘? - 最好是,当该过程开始和结束时?

EDIT1 我们对测量应用程序行为特别感兴趣,我们希望通过将参数更改为open()来避免更改应用程序的语义 - 添加O_SYNC - 或者注入sync()。通过更改应用程序语义,您无法实际讲述原始应用程序的行为。

3 个答案:

答案 0 :(得分:3)

您可以将文件打开为O_SYNC,理论上这意味着写入不会返回,直到数据写入磁盘。虽然所写的数据,实际或元数据是依赖于文件系统及其安装方式。这改变了你的应用程序的工作方式。

如果你真的真的对自己处理存储的实际I / O感兴趣(你是数据库吗?)那么O_DIRECT会让你失控。同样,这是行为的变化,并对您的应用程序施加了额外的限制。它可能是你需要的,也可能不是。

你似乎真的在询问基准实际表现,所以真正的问题是你想知道什么。由于真正的系统可以进行如此多的缓存,因此"即时"从写作回来是真实的"从你的应用程序实际延迟的角度来看。如果您正在寻找I / O吞吐量,那么您可能会更好地查看更高级别的系统统计信息。

答案 1 :(得分:2)

您基本上无法知道数据何时真正写入磁盘,并且实际的磁盘写入可能会在您的进程终止(通常是几分钟)后很长时间内发生。此外,您的磁盘本身(在磁盘控制器内)有一些缓存。对此感到高兴,因为系统的page cache非常有效(并使Linux系统快速运行)。

你可能会考虑调用sync(2)系统调用,但是你经常不应该(它可能很慢,但仍然不保证任何写入,它通常要求内核稍后刷新缓冲区)。

在给定的打开文件描述符上,您可以考虑fsync(2)。如Joe answered,您可以将O_SYNC传递给open,但这会降低系统速度。

我强烈建议(出于性能原因)信任您的内核页面缓存管理,并避免手动强制执行任何磁盘刷新。另请参阅相关的posix_fadvise(2)& madvise(2)系统调用。

如果您对一些程序进行基准测试,请多次运行(并考虑对您最重要的事项:测量时间的平均值 - 可能排除最佳和/或最差的 - 或者更糟或最好他们)。所以关键是应用程序的I / O时间(或CPU时间,或实际经过的时间)是非常不明确的东西。您可能希望在发布基准测试结果时解释您的基准测试过程。

答案 2 :(得分:0)

您可以参考此链接。它可能对你有帮助。 Flush Data to disk

就写入磁盘而言,这是不可预测的。没有明确的方式来表达它。但您可以通过调用sync来确保将数据写入磁盘。