我正在尝试在C++中编写一个类,它提供了一种原子追加到文件的方法,即使在停电中写入的情况下也是如此。首先,我将当前文件位置(距离文件开头的64个偏移量,以字节为单位)写入单独的日志文件。然后,我将请求的数据写入日期文件的末尾。最后,我在日志文件中调用ftruncate()(将截断大小设置为0)。ftruncate()是异步的吗?
主要思想是,如果这个类有人要求打开一个非空的日志文件的文件,那么你知道一个写入被中断,你可以从日志文件和fseek读取最后写入的位置到那个地方。你失去了最后的部分写入,但该文件不应该被损坏。
不幸的是,似乎ftruncate()是异步的。实际上,即使我在ftruncate之后调用fflush()和fsync(),我也会看到日志在进行大量写操作时增长到高达数百个字节。它总是最终以0结束,但我期望在任何时候都能看到0或8的大小。
是否有可能使ftruncate完全同步?或者有更好的方式来使用期刊?
呃电源故障? – 2012-02-06 00:57:18
如果在恢复日志期间再次断电,该怎么办? – 2012-02-06 00:59:24
“有没有更好的方式来使用期刊?” - 取决于您的恢复要求。在你的数据文件中写入一些“下一块应该是N字节”的消息将避免需要单独的日志(并且头部重新定位在磁性HDD上很慢),假设在恢复情况下你有时间从开始重新扫描文件 - 沿着块跳转,或者当从文件末尾向后扫描时,可以将这种下一块N字节内容与其他内容区分开。内存映射对日记来说可能更优雅一些。 – 2012-02-06 01:43:44