【问题标题】:Atomic delete for large amounts of files大量文件的原子删除
【发布时间】:2010-12-10 00:07:07
【问题描述】:

我正在尝试一次删除 10000 多个文件,例如以原子方式删除要么全部删除,要么全部保留。

当然,显而易见的答案是将所有文件移动到一个临时目录中,并在成功时递归删除它,但这会使所需的 I/O 量翻倍。

压缩不起作用,因为1)我不知道哪些文件需要删除,2)文件需要经常编辑。

有什么东西可以帮助降低 I/O 成本吗?任何平台都可以。

编辑:假设停电随时可能发生。

【问题讨论】:

    标签: c++ c file io atomic


    【解决方案1】:

    Kibbee 是正确的:您正在寻找交易。但是,如果您不想的话,您不需要依赖数据库或特殊文件系统功能。交易的本质是这样的:

    1. 将记录写入一个特殊文件(通常称为“日志”),其中列出了您要删除的文件。
    2. 安全写入此记录后,请确保您的应用程序的行为就像文件已被实际删除一样。
    3. 稍后,开始删除交易记录中指定的文件。
    4. 删除所有文件后,删除交易记录。

    请注意,在第 (1) 步之后的任何时候,您都可以重新启动应用程序,它会继续删除逻辑删除的文件,直到它们最终全部消失。

    请注意,您不应该走得太远:否则您将开始重新实现真正的交易系统。但是,如果您只需要很少的简单事务,那么您自己的方法可能是可以接受的。

    【讨论】:

    • +1:标记删除;停止使用。之后的任何时间都可能发生物理删除。
    • 如果发生某些事情导致其中一个文件不可删除,例如其中一个文件正在被另一个进程使用,该怎么办。您可以等待它被释放,但这可能需要一段时间。如果无法删除所有内容,您将如何回滚?
    • 这正是我所需要的。 +1 表示“我为什么没想到?”
    • @Kibbee:在我的情况下,只有当我忘记删除过程时才需要回滚,例如通过重启。日志文件确保不会发生这种情况。
    • 还有一点需要注意:知道日志记录何时“安全写入”本身就是一个有趣的问题。通常的 unix 答案是 fsync() 系统调用,它保证文件的当前内容完全反映在磁盘上。当然,如果您的磁盘启用了写入缓存(许多消费者磁盘都启用了),那么您仍然可能在某种崩溃时丢失日志文件。这一点的重要性取决于相关应用程序的重要性。
    【解决方案2】:

    您的问题的基本答案是“不”。更复杂的答案是,这需要文件系统的支持,而且很少有文件系统有这种支持。显然 NT 有一个事务性 FS 支持这一点。 BtrFS for Linux 可能也会支持这一点。

    在没有直接支持的情况下,我认为硬链接、移动、删除选项是您将获得的最佳选择。

    【讨论】:

      【解决方案3】:

      在 Windows Vista 或更高版本上,Transactional NTFS 应该可以满足您的需求:

      HANDLE txn = CreateTransaction(NULL, 0, 0, 0, 0, NULL /* or timeout */, TEXT("Deleting stuff"));
      if (txn == INVALID_HANDLE_VALUE) {
        /* explode */
      }
      if (!DeleteFileTransacted(filename, txn)) {
        RollbackTransaction(txn); // You saw nothing.
        CloseHandle(txn);
        die_horribly();
      }
      if (!CommitTransaction(txn)) {
        CloseHandle(txn);
        die_horribly();
      }
      CloseHandle(txn);
      

      【讨论】:

        【解决方案4】:

        您不能只建立要删除的路径名列表,将此列表写入文件to_be_deleted.log,确保该文件已进入磁盘(fsync()),然后开始执行删除操作。完成所有删除后,删除to_be_deleted.log 事务日志。

        当您启动应用程序时,它应该检查to_be_deleted.log 是否存在,如果存在,则重播该文件中的删除操作(忽略“不存在”错误)。

        【讨论】:

          【解决方案5】:

          您是否有用于访问文件的抽象层(例如数据库)? (如果您的软件直接进入文件系统,那么我的建议不适用)。

          如果删除文件的条件是“正确”,则在抽象层中将状态更改为“已删除”并开始后台作业以“真正”从文件系统中删除它们。

          当然,这个提议在打开/关闭文件时会产生一定的成本,但会在创建符号链接等方面为您节省一些 I/O。

          【讨论】:

            【解决方案6】:

            我认为复制然后删除方法几乎是执行此操作的标准方法。你知道你不能容忍额外的 I/O 吗?

            我不会把自己算作文件系统的导出,但我想任何执行事务的实现都需要首先尝试执行所有所需的操作,然后它需要返回并提交那些行动。 IE。与非原子方式相比,您无法避免执行更多的 I/O。

            【讨论】:

              【解决方案7】:

              在 *nix 上,在单个文件系统中移动文件是一项成本非常低的操作,它通过硬链接到新名称然后取消链接原始文件来工作。它甚至不会改变任何文件时间。

              如果您可以将文件移动到单个目录中,那么您可以重命名该目录以使其成为真正的原子操作,然后稍后以较慢的非原子操作删除文件(和目录)时尚。

              你确定你不只是想要一个数据库吗?它们都内置了事务提交和回滚。

              【讨论】:

              • 为什么你认为搬家比删除便宜?
              • 由于我不提前知道哪些文件会被删除,所以这种方法仍然比我的重命名目录贵。不过会很好。
              • @ralu:所有交易系统所做的都是记录意图并识别和协调不归路点,然后再做任何无法逆转的事情。我试图调用一种事务性方法来删除文件。它比仅仅使用unlink(2) 有更多的开销,但这就是进行交易的代价。不过,我可能应该这么说。
              • DigitalRoss 是对的。在给出的示例中,搬家要便宜得多。一旦您开始取消链接整个目录结构,您将淹没 VFS,并失去任何原子性的可能性。
              【解决方案8】:

              我认为您真正需要的是进行交易的能力。由于光盘一次只能写入一个扇区,因此您一次只能删除一个文件。如果其中一个删除没有成功发生,您需要的是能够回滚以前的删除。像这样的任务通常是为数据库保留的。您的文件系统是否可以执行事务取决于您使用的文件系统和操作系统。 Windows Vista 上的 NTFS 支持Transactional NTFS。我不太确定它是如何工作的,但它可能很有用。

              此外,Windows 中还有一个名为 shadow copy 的东西,在 Linux 世界中称为 LVM Snapshot。基本上它是光盘在某个时间点的快照。您可以在删除之前直接拍摄快照,如果没有成功,请将文件从快照中复制回来。我已经在 VBScript 中使用 WMI 创建了卷影副本,我确信 C/C++ 也存在类似的 api。

              关于卷影复制和 LVM 快照的一件事。整个分区的工作。因此,您不能只拍摄单个目录的快照。但是,拍摄整个磁盘的快照只需要几秒钟。所以你会拍一张快照。删除文件,如果不成功,将文件从快照中复制回来。这会很慢,但取决于您计划回滚的频率,它可能是可以接受的。另一个想法是恢复整个快照。这可能好也可能不好,因为它会回滚整个磁盘上的所有更改。如果您的操作系统或其他重要文件位于那里,那就不好了。如果此分区仅包含您要删除的文件,则恢复整个快照可能会更容易、更快捷。

              【讨论】:

                【解决方案9】:

                不要移动文件,而是在临时目录中建立符号链接。然后,如果一切正常,请删除文件。或者,只需在某处列出文件列表,然后将其删除。

                【讨论】:

                  猜你喜欢
                  • 2019-11-01
                  • 1970-01-01
                  • 2011-10-20
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-12-26
                  • 2013-11-23
                  相关资源
                  最近更新 更多