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

标签 io aio fsync

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

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

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

最佳答案

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

只要您等待任何未完成的异步 I/O 完成,您就可以发送 fsync() 并知道所有先前的 I/O 已写入稳定存储Linux 内核的最佳知识*

does fsync() exclusively works for synchronous I/O?

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

is fsync() after io_submit() an undefined behavior?

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

how to make asynchronous write safely persisted to the device medium rather than device cache (no battery-backed cache).

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


* 我排除了发生错误的情况,因为它们相当复杂。请参阅Writing programs to cope with I/O errors causing lost writes on Linux详细解释。

关于io - 如果我使用 libaio + fsync() 会怎样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66073136/

相关文章:

io - 内存映射 IO 与 DMA?

c++ - 为什么循环是无限的?

java - 如何读取 .txt 文件并每 8 个字符分割一次?

java - 大字节数组传输到客户端

c - 使用 Linux AIO 写入 eventfd

c - Posix AIO 损坏/损坏?

clojure - 维护多个打开的文件以进行写入 (Clojure)

linux-kernel - fsync/FlushFileBuffers 是否等待未完成的异步 IO 完成?

linux - 如何跟踪在 Ubuntu Linux 中读/写到磁盘的总数据(包括元数据)?