如果我使用 libaio + fsync() 会怎样?
What will be if I use libaio + fsync()?
我知道当我使用 write()
+ fsync()
(或 O_SYNC
+ write()
写文件时,我认为它们是相同的 ref #2),这意味着我正在使用阻塞同步 I/O,如果 write()
(with O_SYNC
) 或 fsync()
returns,则意味着数据安全地在设备介质(例如,用于 SSD 的 TLC NAND)而不是设备缓存(例如,SSD 中的 DDRAM)。
而如果我使用 libaio
呢? (因为我想确保 libaio 发出的写入是在存储介质上而不是设备缓存上。也就是说,我想当 io_getevents()
returns 时,它可能无法确保写入在存储上介质,它可能只在设备缓存中)
- 问题 1:
fsync()
是否只适用于同步 I/O?
- 问题2:
io_submit()
之后的fsync()
是未定义的行为吗?
- 问题 3:如何使异步写入安全地持久化到设备介质而不是设备缓存(无电池后备缓存)。
(本回答只是从Linux的角度来看问题,其他操作系统可能会有不同behaviour/semantics)
只要您等待任何未完成的异步 I/O 完成,您就可以发送您的 fsync()
并知道所有先前的 I/O 已写入稳定存储根据 Linux 内核的最佳知识*.
does fsync() exclusively works for synchronous I/O?
这个问题没有意义。 fsync()
在 I/O 上工作,Linux 同意已“发送”,然后还刷新设备缓存。如果您向内核异步发送 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()
并等待它或 ( ). Another libaio
technique is to set the RWF_SYNC
flag during io_submit()
. If you were using io_uring
你会有另一个选择,因为你可以使用它的链接并且它有一个异步 fsync
操作 (IORING_OP_FSYNC
)。
* 我排除了发生错误的情况,因为它们相当复杂。有关详细说明,请参阅 Writing programs to cope with I/O errors causing lost writes on Linux。
我知道当我使用 write()
+ fsync()
(或 O_SYNC
+ write()
写文件时,我认为它们是相同的 write()
(with O_SYNC
) 或 fsync()
returns,则意味着数据安全地在设备介质(例如,用于 SSD 的 TLC NAND)而不是设备缓存(例如,SSD 中的 DDRAM)。
而如果我使用 libaio
呢? (因为我想确保 libaio 发出的写入是在存储介质上而不是设备缓存上。也就是说,我想当 io_getevents()
returns 时,它可能无法确保写入在存储上介质,它可能只在设备缓存中)
- 问题 1:
fsync()
是否只适用于同步 I/O? - 问题2:
io_submit()
之后的fsync()
是未定义的行为吗? - 问题 3:如何使异步写入安全地持久化到设备介质而不是设备缓存(无电池后备缓存)。
(本回答只是从Linux的角度来看问题,其他操作系统可能会有不同behaviour/semantics)
只要您等待任何未完成的异步 I/O 完成,您就可以发送您的 fsync()
并知道所有先前的 I/O 已写入稳定存储根据 Linux 内核的最佳知识*.
does fsync() exclusively works for synchronous I/O?
这个问题没有意义。 fsync()
在 I/O 上工作,Linux 同意已“发送”,然后还刷新设备缓存。如果您向内核异步发送 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()
并等待它或 ( libaio
technique is to set the RWF_SYNC
flag during io_submit()
. If you were using io_uring
你会有另一个选择,因为你可以使用它的链接并且它有一个异步 fsync
操作 (IORING_OP_FSYNC
)。
* 我排除了发生错误的情况,因为它们相当复杂。有关详细说明,请参阅 Writing programs to cope with I/O errors causing lost writes on Linux。