我知道这个问题的答案通常是“当它认为合适时”,或者其他一些晦涩的答案。我多次看到,如果主机硬启动,一些最近写入的文件没有最后的数据,甚至被损坏。但最近我正在帮助某人调试导致大量 I/O 的代码。仔细查看后发现,这是一段写得非常糟糕的代码,它使用打开一个临时文件tmpfile(3)
(这意味着该文件在打开后立即取消链接),然后重复以下步骤数千次:
- 向文件写入几个字节。
- 使用 移回到文件的开头
seek
。 - 读取这几个字节。
- 使用将文件截断为零
ftruncate
。
然后它一次又一次地做同样的动作。由于文件系统是xfs,并且最小文件大小为4k,因此似乎在计算此循环重复的次数并乘以4k时,它恰好达到了系统报告的I/O写入量,因此似乎在每次之后ftruncate
,或者write
紧随其后,在磁盘上分配了一个新块。这在主机上造成了很多问题iowait
,当这些进程中的几个进程在同一台主机上一起运行时,它就会真正加载并且磁盘速度非常慢。
现在,抛开这段非常低效的代码(在我的发现后已修复),它让我想知道为什么 I/O 负载如此之高。看起来数据被一次又一次地刷新,并且每个ftruncate
(或write
之后的)一次又一次地分配4k。因此,我试图弄清楚数据(以及哪些数据)如何以及何时刷新到物理磁盘。仅仅是元数据,还是数据本身?
顺便说一句,不要用或或类似的东西tmpfile
打开文件。O_SYNC
O_DIRECT