起源

起源

起源

https://btrfs.wiki.kernel.org/index.php/FAQ#What_are_the_crash_guarantees_of_overwrite-by-rename.3F

使用重命名覆盖现有文件是原子的。这意味着文件的旧内容或新内容存在。像这样的序列:

echo "oldcontent" > file

# make sure oldcontent is on disk
sync

echo "newcontent" > file.tmp
mv -f file.tmp file

# *crash*

会给

文件包含“新内容”; file.tmp 不存在
包含“oldcontent”的文件; file.tmp 可能包含“newcontent”、长度为零或根本不存在。

这种方法保证保持file一致(它将具有“新内容”或“旧内容”),但新数据可能会也可能不会在崩溃后恢复。 (mv file.tmp file甚至给出更有趣的结果

问题

我想实现一种在崩溃时恢复操作的方法,这样我就不会丢失“旧内容”或“新内容”。我怎样才能做到这一点?

它能保证有:

  • 要么file有“旧内容”,要么file.tmp有“新内容”
  • 或者file有“newcontent”并且file.tmp不存在:
echo "oldcontent" > file

echo "newcontent" > file.tmp

# make sure files are on disk
sync

# a crash may happen at any time starting from this point.

ln file.tmp file.tmp2
mv -f file.tmp2 file
rm file.tmp

答案1

通过移动syncafter echo "newcontent" > file.tmp,您可以确保两个文件的内容都在磁盘上。这消除了“files.tmp可能为零长度”的变体。

剩下的不确定性,如果崩溃发生在之后sync,只涉及目录条目,IE哪个文件指向哪里。移动 后sync,剩下的可能性就是您列出的那些:

  • file存在并包含“旧内容”,并且file.tmp存在并包含“新内容”;
  • file存在并包含“newcontent”,但file.tmp不存在。

无需通过链接到file.tmp其他地方来添加额外的故障保护。

移动确实sync会产生其他后果:特别是,它会为数据丢失留下更多的时间sync

相关内容