gpt4 book ai didi

file-io - 在非事务性文件系统中实现原子文件写入

转载 作者:行者123 更新时间:2023-12-02 10:17:09 24 4
gpt4 key购买 nike

许多常见的文件系统不提供原子操作,但在某些场景下以原子方式写入文件非常重要。我试图想出一个解决这个问题的方法。

我做了以下假设:

  • 所使用的文件系统支持 inode 级别的原子操作(例如 NTFS)。这意味着移动删除是原子的。
  • 只有程序本身才能访问这些文件。
  • 该程序一次只有 1 个实例,并且以单线程方式运行。
  • 为简单起见,每次都会写入整个文件内容(即截断写入)。

这会带来以下问题:在写入文件时,程序可能会被中断,文件将只剩下部分内容可供写入。

我建议以下流程:

  1. 将新内容写入临时文件新建
  2. 将原始文件原始移动到临时位置备份
  3. 移至原始
  4. 删除备份

备份文件与原始文件不同(例如,它们可以有不同的前缀,或者可以位于单独的目录中在同一卷上)。同时,它们的名称应直接映射到相应的原始(例如简单地使用相同的文件名)。

但是,这还没有使操作成为原子操作。该过程可能会被步骤 1、2、3 或 4 中断:

  1. 留下可能不完整的
  2. 移动是原子的,但目标文件现在丢失。 新建备份均存在且完整。
  3. 移动是原子的,但有一个未使用的备份原始已被内容替换
  4. 删除是原子性的。

使用前面的假设 2 和 3,程序在崩溃后必须重新启动。在启动过程中,它应该执行这些恢复检查:

  • 如果New存在,但Backup不存在,则我们在步骤1中或之后崩溃。删除New,因为它可能不完整。
  • 如果New存在且Backup也存在,则我们在第2步后崩溃。继续第3步。
  • 如果备份存在,但新建也不存在,则我们在步骤 3 后崩溃。继续执行步骤 4。

恢复过程本身仅使用原子操作,在被中断后将简单地从中断处继续。

我相信这个想法可以确保单个程序的原子写入。这些问题仍然存在:

  • 使用同一程序的多个实例时,恢复过程会干扰其他程序中当前正在进行的文件写入。
  • 只读而不写的外部程序通常会得到正确的结果,但如果同时对请求的条目进行写操作,它们可能会错误地找不到条目。

这些问题(之前的假设已排除)可以通过使用策略来解决(例如,检查其他实例,并拒绝其他用户的目录访问)。

最后,我的问题是:这有意义吗?或者过程中是否存在缺陷?是否有任何问题阻碍这种方法在实践中使用?

最佳答案

您应该假设只有一件事,重命名文件是原子操作

因此以下步骤将确保纠正(至少在类似 UNIX 的操作系统上)

  1. 将新内容写入临时文件新建
  2. 将临时文件重命名为原来的名称

这样,如果应用程序在重新启动时崩溃,它可以获取旧内容或新内容,而无需额外的代码。

关于file-io - 在非事务性文件系统中实现原子文件写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9096380/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com