Python 原子写入多个文件

Python 原子写入多个文件,python,database,synchronization,filesystems,atomicity,Python,Database,Synchronization,Filesystems,Atomicity,假设我有一组文件。如何确保对所有这些文件的写入是原子的 我考虑过写入临时文件,只有在写入成功后,才对每个文件执行原子重命名。然而,一次重命名所有文件并不是原子的。此外,如果我们想附加到这些文件中,这将不会扩展到非常大的文件 相反,我考虑过实现事务,但这本身就成了一个项目。我意识到这主要是实现一个迷你数据库 您将如何在Python中实现它 d = FileWriter.open(['file1', 'file2'], 'wb+') d.write('add hello world to files

假设我有一组文件。如何确保对所有这些文件的写入是原子的

我考虑过写入临时文件,只有在写入成功后,才对每个文件执行原子重命名。然而,一次重命名所有文件并不是原子的。此外,如果我们想附加到这些文件中,这将不会扩展到非常大的文件

相反,我考虑过实现事务,但这本身就成了一个项目。我意识到这主要是实现一个迷你数据库

您将如何在Python中实现它

d = FileWriter.open(['file1', 'file2'], 'wb+')
d.write('add hello world to files')
d.close()

确保d.write是原子的,或者如果不成功,至少回滚到原始文件。

您可以尝试使用来实现您的目标。它可以在python中通过
fcntl.flock
实现。请注意,这只是一项建议措施。为了真正保证您想要的,您应该尝试使用支持严格锁定的数据库或文件系统/内核。

以下是我的想法。首先确保open已同步,然后执行以下操作:

  • 写入临时文件:file1~、file2~和特殊文件success~(必须先写入)
  • 成功写入后,删除文件success~
  • 将文件重命名为file1和file2
  • 如果有东西坏了:

  • 检查success~是否存在
  • 如果有,不要费心修理。由于文件未更新(未重命名),因此隐式执行了回滚
  • 如果success~不存在,则在编写后和重命名过程中会出现问题。在这种情况下,修复就像将filex~重命名为filex一样简单

  • 在当前的声明中,您的需求非常通用,唯一合理的答案是操作系统级支持是必要的,而且它甚至不再是严格意义上的Python相关问题。请参阅有关事务性文件系统的说明,例如和。关于目前提出的解决方案的一个小摘录:

    如果没有文件系统事务,确保跨多个文件系统操作的一致性即使不是不可能,也是很困难的。文件锁定可以用作单个文件的并发控制机制,但它通常不保护目录结构或文件元数据。例如,文件锁定不能阻止符号链接上的TOCTOU竞争条件。文件锁定也不能自动回滚失败的操作,如软件升级;这需要原子性

    因此,我建议重新思考您的问题(也许您的问题也是如此?),并更详细地分析您的需求。底线是,你需要的保证越少,你就能找到越简单的解决方案。也许你可以做一些简单的事情,比如文件锁定,或者你会发现需要一个数据库


    说到这里,如果您考虑的是文件系统,因为您的体系结构的组件需要访问文件,那么您是否考虑过在常规数据库之上构建类似文件系统的外观?使用是件轻而易举的事。

    数据库管理系统通常只使用一个预写日志文件,或者使用自定义文件系统的原因是,通常的文件系统在保证原子性或执行顺序方面非常糟糕

    它们完全针对一致性和性能进行了优化

    因此,除非使用专用文件系统创建分区或映像文件,否则只能信任写入单个文件的顺序

    不过,您可以在每次写入多个文件时写入事务编号

    并明确写操作是否完成,例如,使用带有开始/结束标记的xml或json样式块,如。。。或{…},&c

    然后,您的代码可以轻松地检测多个文件之间的任何间隙,并确定崩溃后的最后一个一致状态

    为了避免崩溃后的最后一个一致状态由于某些写操作已在缓存中等待数分钟而变得任意陈旧,这些方法中的任何一种都可以与sync/fsync结合使用

    使用sync/fsync还使事务提交成为可能,也就是说,确保至少从文件系统的角度来看,到目前为止所有内容都是编写的

    但是,您的存储系统可能会因为断电而丢失最后一次写入,无论是硬盘还是带有内部缓存、NAS和c的SSD。 这些系统提供的保证可能差异很大,无论是使用文件系统还是传统的RDBMS进行存储,这都是一个需要考虑的挑战


    如果您正在写入内置硬盘或SSD,那么使用UPS肯定是一个很好的补充,尤其是当USP发出信号表示即将关闭系统时,以受控方式关闭系统。^^

    nt文件锁定(几乎每个文件系统都实现)是否确保原子操作
    d=FileWriter.open(['file1','file2'],'wb+')
    我认为这条语句会对该文件设置写锁。你唯一需要确保的是另一个进程检查文件的锁定状态。我刚刚编了一个FileWriter。天真的是,它会顺序写入两个文件。如果中间发生了什么事,你就不走运了。假设这些文件代表一个搜索引擎索引。因为您只写了一个文件而没有写另一个,所以现在索引已损坏。a好的,我漏了一点。您需要对所有文件执行原子操作,为什么不使用数据库呢?这就是他们擅长的。我想我能做的就是有一个修复机制。如果出现问题,请修复这些文件。当数据库带有此内置程序时,为什么要经历所有这些麻烦呢?因为我希望这些文件是纯文本的,便于人类阅读。我还希望这些文件能够在用户之间轻松共享。事实上,我希望任何知道这些文件格式的人都能够在不使用x数据库的情况下创建它们。这是一个小型搜索引擎索引。另外,这有点像回答一个问题