【问题标题】:Implementing atomic file writes in a nontransactional filesystem在非事务性文件系统中实现原子文件写入
【发布时间】:2012-02-01 13:11:42
【问题描述】:

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

我做了以下假设:

  • 正在使用的文件系统支持 inode 级别的原子操作(例如 NTFS)。这意味着 movedelete 是原子的。
  • 只有程序本身才能访问文件。
  • 一次只有一个程序实例,它以单线程方式运行。
  • 为简单起见,每次都写入整个文件内容(即 truncate-write)。

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

我提出以下流程:

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

NewBackup 文件与 Original 文件有区别(例如,它们的前缀可能不同,或者可能位于单独的目录中在同一卷上)。同时,它们的名称应该直接映射到相应的Original(例如通过简单地使用相同的文件名)。

然而,这并没有使操作原子化。该过程可能会被第 1、2、3 或 4 步中断:

  1. 留下一个可能不完整的
  2. 移动是原子的,但现在缺少目标文件。 新建备份都存在并且是完整的。
  3. 移动是原子的,但有一个未使用的备份原来的新的内容替换了
  4. 删除是原子的。

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

  • 如果 New 存在但 Backup 不存在,我们在步骤 1 中或之后崩溃。删除 New,因为它可能不完整。李>
  • 如果 New 存在并且 Backup 也存在,我们会在第 2 步后崩溃。继续第 3 步。
  • 如果 Backup 存在但 New 也不存在,我们在第 3 步后崩溃。继续第 4 步。

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

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

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

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

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

【问题讨论】:

  • 我为此写了一些 C# 代码,我可以根据要求添加它,但问题已经一英里长了。

标签: file-io transactions filesystems atomic


【解决方案1】:

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

因此,以下步骤将确保更正(至少在 unix 之类的操作系统上)

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

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

【讨论】:

  • 这不起作用,因为必须删除旧文件才能启用重命名。
  • @mafutrct:不正确;重命名可以覆盖(至少在 Unix 上)。
  • 警告:某些文件系统不保证在提交元数据之前将数据块写入磁盘。在这种情况下,您可能必须在写入临时文件之后但在重命名之前调用 fdatasync() 或等效项。
【解决方案2】:

您的步骤可以进一步简化:

  1. 将新内容写入临时文件 新建
  2. 删除原始文件
  3. 从新到原来的移动

启动时:

  1. 如果 Original 不存在但 New 存在,则该过程在第 3 步之前被中断,将 New 移至 Original。
  2. 如果 Original 和 New 都存在,则流程在第 2 步之前中断,删除 New。

我在管理配置文件时使用了它,并且从未遇到过这个过程中的问题。

【讨论】:

  • 您假设您指定的操作按顺序发生。并非每个文件系统都能保证这一点。
  • @CodeInChaos:这太邪恶了:(所以我必须在步骤之间刷新 fs 缓冲区?继续你的想法,我听说硬盘有点忽略刷新请求......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-27
  • 2013-06-07
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 2011-06-14
相关资源
最近更新 更多