gpt4 book ai didi

linux - 可以通过每次提交使用单个 fsync 来实现日志记录吗?

转载 作者:太空狗 更新时间:2023-10-29 11:40:03 24 4
gpt4 key购买 nike

假设您正在构建一个日记/预写日志存储系统。您能否通过(针对每个事务)附加数据(使用 write(2))、附加提交标记,然后 fsync-ing 来简单地实现这一点?

要考虑的场景是,如果您对该日志进行大量写入,然后对其进行 fsync,并且 在 fsync 期间 出现故障。 inode 直接/间接 block 指针是否仅在所有数据 block 都被刷新后才被刷新,或者是否不能保证 block 被按顺序刷新?如果是后者,那么在恢复期间,如果您在文件末尾看到一个提交标记,您就不能相信它与前一个提交标记之间的数据是有意义的。因此,您必须依赖另一种机制(至少涉及另一个 fsync)来确定日志文件的一致范围(例如,写入/fsyncing 数据,然后写入/fsyncing 提交标记)。

如果它有所不同,主要是想知道 ext3/ext4 作为上下文。

最佳答案

注意linux和mac os的fsync和fdatasync默认是不正确的。 Windows 默认是正确的,但可以模拟 linux 以进行基准测试。

此外,如果您追加到文件末尾,fdatasync 会发出多次磁盘写入,因为它需要用新长度更新文件 inode 。如果您希望每次提交都写入一次,最好的办法是预先分配日志空间,将日志条目的 CRC 存储在提交标记中,并在提交时发出单个 fdatasync()。这样,无论操作系统/硬件在您背后重新排序多少,您都可以找到实际命中磁盘的日志前缀。

如果您想将日志用于持久提交或预写,事情会变得更难,因为您需要确保 fsync 确实有效。在 Linux 下,您需要使用 hdparm 禁用磁盘写缓存,或者将 barrier 设置为 true 来挂载分区。 [编辑:我被纠正了,屏障似乎没有给出正确的语义。 SATA 和 SCSI 引入了许多原语,例如写屏障和 native 命令队列,这使得操作系统可以导出启用预写日志记录的原语。从我从联机帮助页和在线内容中可以看出,Linux 只将这些公开给文件系统开发人员,而不是用户空间。]

自相矛盾的是,禁用磁盘写入缓存有时会带来更好的性能,因为您可以更好地控制用户空间中的写入调度;如果磁盘排队一堆同步写请求,您最终会向应用程序暴露奇怪的延迟峰值。禁用写入缓存可防止这种情况发生。

最后,真实系统使用组提交,并在并发工作负载下每次提交执行 < 1 次同步写入。

关于linux - 可以通过每次提交使用单个 fsync 来实现日志记录吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3800108/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com