【发布时间】:2023-03-15 06:43:01
【问题描述】:
我正在使用 C++ ofstream 在 Linux 上编写日志文件。当我使用 tail -f 命令监视文件内容时,我可以看到内容已正确填充。但是如果发生停电并且我在重启后再次检查文件,最后几行记录就消失了。使用 hexdump 我可以看到这些记录变成了空字符 '\0'。我尝试了 flush() 和 manipulator std::endl ,但它们无论如何都没有帮助。
tail 显示给我的内容是否真的没有写入磁盘,它们只是在缓冲区中?停电前inode表没有更新?我可以接受这个事实,但我不明白为什么如果没有写入文件,记录会变成空字符。
顺便说一句,我尝试了谷歌的 glog 并且得到了相同的结果(最后一堆空字符)。我还尝试了 zlog,一个 C 库。发现它只丢失了最后的记录,但没有用空字符替换它们。
【问题讨论】:
-
使用同步而不是刷新。 stackoverflow.com/questions/14251873/… 的可能重复项
-
纯属假设性解释:
tail显示的是操作系统缓存或磁盘控制器缓冲区的内容。文件已扩展(零),内容(可能)已写入磁盘控制器的缓冲区,但控制器尚未将其缓冲区写入磁盘。 -
@molbdnilo 我认为您建议立即更新文件系统以反映文件的新大小,但数据从未有机会被磁盘控制器写入磁盘。那么谁决定实际写入数据,操作系统?磁盘控制器固件?
-
@Donghui 我知道同步可以比刷新做得更好,但它会带来日志记录成本。我想这就是为什么不是每个日志库,例如glog,如果它更喜欢性能而不是一致性,则使用这种方式。
-
是的,这是一个权衡