如果我使用 libaio + fsync() 会怎样?

问题描述

我知道当我使用 write() + fsync()(或 O_SYNC + write() 编写文件时,我认为它们是相同的 ref #1 {{3} }),这意味着我正在使用阻塞同步 I/O,并且如果 write()(with O_SYNC) 或 fsync() 返回,则意味着数据安全地在设备介质上(例如,用于 SSD 的 TLC NAND)而不是设备缓存(例如,SSD 中的 DDRAM)。

如果我使用 libaio 会怎样? (因为我想确保 libaio 发出的写入在存储介质上而不是设备缓存上。即,我想当 io_getevents() 返回时,它可能无法确保写入在存储介质上,并且它可能只是在设备缓存上)

  • 问题 1fsync() 是否专门用于同步 I/O?
  • 问题 2fsync() 之后的 io_submit() 是未定义的行为吗?
  • 问题 3:如何使异步写入安全地持久保存到设备介质而不是设备缓存(无电池备份缓存)。

解决方法

(这个答案只是从 Linux 的角度来看问题。其他操作系统可能有不同的行为/语义)

只要您等待任何未完成的异步 I/O 完成,您就可以向下发送您的 fsync() 并知道所有先前的 I/O 都已写入稳定存储,并尽全力了解Linux 内核*.

fsync() 是否专门用于同步 I/O?

这个问题没有意义。 fsync() 适用于 Linux 同意已“发送”的 I/O,然后还会刷新设备缓存。如果您向内核异步发送 I/O,内核是否同意它已“发送”?另请参阅最后一个问题的答案...

io_submit() 之后的 fsync() 是未定义的行为吗?

从技术上讲,undefined behaviour 意味着从那时起,任何事情都将被允许合法发生(例如所谓的鼻守护进程)。情况并非如此,但我认为您是在问您的第一个问题,因此那里的答案仍然成立。

如何使异步写入安全地持久化到设备介质而不是设备缓存(无电池备份缓存)。

如果您在使用 libaio 时遇到困难,您可以通过等待所有未完成的 I/O 完成然后发送 fsync() 并等待它或 ({{3} })。另一种 libaio 技术是在 RWF_SYNC 期间设置 io_submit() 标志。如果您使用的是 as mentioned in a comment,您还有另一个选择,因为您可以使用它的链接,并且它具有异步 fsync 操作 (IORING_OP_FSYNC)。


* 我排除了发生错误的情况,因为它们相当复杂。有关详细说明,请参阅 io_uring

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...