重写现有文件,以便原子地将其替换为新版本,只有完全写入一次


18

我隐约记得在某些地方阅读某处曾经有一种打开现有文件进行写入的方式,它带有一个标志,要求内核使用旧版本(供其他进程访问以进行读取),直到“新版本已完全写入(fd已关闭),此后文件将显示为新版本。

换句话说,其他进程要么看到的是旧版本,要么看到的是新版本,而从来没有看到不完整的版本。

有知识的人可以为我提供参考吗?


听起来像计划9可能会做的一样,但没有。
吉尔斯(Gilles)“所以,别再邪恶了”,

2
听起来像OpenVMS上的Files-11:“每次保存文件而不是覆盖现有版本时,都会创建一个具有相同名称但版本号增加的新文件。”
马太福音

你为什么问?您是否需要该功能,还是只是出于好奇?
尼尔斯2012年

1
我很高兴拥有该功能,并且回想起曾经读过的地方。因此,既需要又有好奇心。
eudoxos 2012年

所有Unix系统都以另一种方式允许这样做-在同一目录中创建新文件,填充更改后的内容并进行原子重命名。对于较小的更改而言,这要贵得多,但是可以工作。
Netch 2012年

Answers:


14

您所描述的内容听起来完全像是用于覆盖文件的基本重命名。

重命名/移动一个文件到另一个文件时,旧文件将取消链接。意味着该文件仍然存在,但不再存在于文件系统树中。因此,只要保持打开状态,旧应用程序将继续能够访问该文件。一旦所有应用程序都关闭了旧文件,则实际上将其未分配到磁盘上。

rename系统调用是一个原子操作。因此,您可以使用其他名称创建一个新文件,然后调用rename将临时文件重命名为您要替换的文件。由于此操作是原子操作,因此绝对没有文件丢失的时间段。它立即从旧文件变为新文件。
请注意,尽管临时文件和要替换的文件必须位于同一安装点上。


仅当您在编写程序时特别考虑了该功能时,才可以使用该功能。但是,在这种情况下,它是一种OS功能,即使是常规程序也会自动获得这种原子语义。
eudoxos 2012年

1
@eudoxos您的评论没有任何意义。您是说程序必须专门编写才能完成rename交换任务。即使您所说的“操作系统功能”已经存在,也必须编写程序来利用它。有什么不同?
Patrick

如果将(可能不受支持的)标志传递给opensyscall,或者必须手动执行描述的操作,则有所不同。
eudoxos 2012年

请记住,要在崩溃时保留旧版本或完全写入的新版本,您还需要使用fsync或类似方法将新文件同步到磁盘上
textshell

@textshell没有同步,您仍然会获得原子性....只是不耐用...正确吗?在这种情况下,我对goo.gl/qfQQfy的参数不了解。在我的情况下,我的系统处于极高的负载下,我想避免文件系统刷新,并且我不在乎文件是否在崩溃后仍然存在。
wcochran

6

正如Patrick所写,执行此操作的通常方法是将新版本写入单独的文件,并在完成后将新版本重命名为旧文件名,并自动进行覆盖。第二个操作称为overwrite-by-rename

现在,一些参考:


man 3p rename告诉我这rename确实是原子的,我想这对所有Linux文件系统都有意义。当我阅读您链接的第一篇文章时,我仍然认为Btrfs重命名操作是原子的。
hagello

1

这使我想起了“ 冲洗分配”。当文件系统使用此功能时,它不是从磁盘的可用空间计数器中​​减去要写入的数据大小,而是将数据直接写入磁盘,而是将数据保留在内存中,直到执行同步系统调用或内核决定冲洗脏缓冲区。

在这种情况下,如果文件正在被一个进程修改,而又被另一个进程打开,则后一个进程将“看到”文件的未修改(或“旧”)版本。

当然,以上内容是理论上的,并且取决于各种因素,我会说出一些不可预测的信息,因为您不确切知道内核何时清除脏页。例如在Linux中(您也可以在了解Linux内核的15.3节中阅读)中,在以下情况下,脏页将被写入磁盘:

  • 页面缓存变得太满,需要更多页面,或者脏页面数变得太大。

  • 自页面变脏以来,已经花费了太多时间。

  • 进程要求清除块设备或特定文件的所有未完成的更改;它通过调用sync(),fsync()或fdatasync()系统调用来实现。

已知此功能可以在HFS +,XFS,Reiser4,ZFS,Btrfs和ext4文件系统中实现。


2
您所描述的是一种文件系统技术,该技术应该在POSIX(文件)系统上对用户空间不可见(因此不会按照您的指示进行操作)(请参阅write:“如果可以(通过任何方式)证明文件数据的read(),要在数据的write()之后发生,即使调用是由不同的进程进行的,它也必须反映该write()。”)。其他进程将不会看到旧的数据(在POSIX)。

感谢您的更正。我想我对这种文件系统技术的理解是错误的。
dkaragasidis

是的,这看起来像其他东西。我现在隐约记得,是在RMS的一次采访中他提到了此功能,也许这是一些旧的奥术系统从未在学术界之外生活过……还是谢谢。
eudoxos 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.