NFS 原子性上的 rename()

NFS 原子性上的 rename()

我有一个流程:

  • 写入一个新的‘.tmp’文件。
  • 使用rename()系统调用来替换现有文件。
  • 正在从远程 NFS 客户端访问该文件。

我们这样做,因为我们想要原子文件更新,并且rename()spec 说:

如果 newpath 已经存在,它将被自动替换,这样尝试访问 newpath 的另一个进程就不会发现它丢失了。但是,可能会有一个窗口,其中 oldpath 和 newpath 都引用被重命名的文件。

我们依赖于这种行为。

但这里有一个问题——就在最近,自从迁移到新的 NetApp(集群模式,从 7 模式)以来——我们遇到了一个偶尔会失败的过程ENOENT——没有这样的文件或目录。

我所说的“非常偶尔”是指过去几周内出现 4 到 5 次,大约每 5 分钟发生一次。

我正在与供应商一起调查这是否是他们的 NFS 服务器的一个错误。

但我实际上想弄清楚的是,这种原子性保证是否真的适用于 NFS。有人能帮我澄清一下原子性保证是否适用rename()于多客户端 NFS 场景吗?我实际上不确定这个功能是否一直在起作用,但从未被保证首先。

从:RFC1813

过程 RENAME 将目录 from.dir 中由 from.name 标识的文件重命名为目录 to.dir 中的 to.name。此操作对于客户端而言必须是原子的。

如果相关的话,我们让 SL 6.5 客户端访问 ONTAP-CDOT 8.3 上的 NFS 数据存储。

答案1

避免 NFS 中的竞争条件

这始终是一个有趣的挑战,我知道的唯一解决方法是无需重写应用程序,使用选项安装共享sync并更改要使用的 NFS 服务器no_wdelay。我不记得如何在 NetApp 中设置 no_wdelay。

这种方法的缺点是,如果您有大量同时写入此共享的内容,它们的速度将呈指数级下降。您可能想问 NetApp 如何在共享上设置 no_wdelay,或者直接向他们描述问题。他们可能有更好的想法。我至少 8 年没有接触过 NetApp 了。

相关内容