use*_*408 4 btrfs deduplication
我有一个 btrfs 卷,我为其创建定期快照。快照会轮换,最旧的为一岁。因此,删除大文件实际上可能在删除后一年内无法释放空间。
\n大约一年前,我将分区复制到更大的驱动器,但仍保留旧分区。
\n现在新驱动器已损坏,因此取出数据的唯一方法是btrfs-restore。据我所知,新驱动器上的数据应该仍然适合旧的、较小的驱动器,并且文件实际上并没有太大变化(最多添加一些新驱动器或删除一些新驱动器,但一年的开销\xe2 \x80\x99s 的快照价值不应很大)。所以我决定将数据恢复到旧驱动器上。
然而,恢复的数据填满旧驱动器的速度比我预期的要快得多。我怀疑这与 btrfs 的实现有关:
\nbtrfs 是否提供了一种机制来通过查找与 \xe2\x80\x9c 遗传相关的 \xe2\x80\x9d 文件来恢复此情况(即通过复制该文件和/或对其所在的子卷进行快照来从同一文件派生),在内容但存储在单独的块集中,并将它们转回引用链接以便可以释放空间?
\nTL;DR:有一些工具可以完成此任务,但不是官方工具套件的一部分,也可能不在您的发行版\xe2\x80\x99s 存储库中。您必须从许多工具中进行选择,并且可能自己构建它。详情请参阅下文。
\nbtrfs wiki 有一篇关于重复数据删除的文章,其中也提到了一些工具。
\n还有更多工具 \xe2\x80\x93 我查看了一个,尽管在撰写本文时它似乎已经有 6 年没有维护了,所以我决定坚持使用 btrfs wiki 上的内容。
\n到目前为止,这些都不是官方 btrfs 套件的一部分,至少 Ubuntu 20.04 没有为它们提供软件包 \xe2\x80\x93 你必须自己构建它们。
\ndduper\xe2\x80\x93 看起来很有前途,它声称可以进行基于文件和块的重复数据删除(即,它对整个文件以及两个或多个文件之间相同的块进行重复数据删除)。据说它也很快,因为它依赖于内部 btrfs 索引。由于它是用 python 编写的,因此不需要在使用前构建(prettytable不过,您的计算机上确实需要 Python 包)。然而,它似乎会跳过任何低于 4 KB 的文件,我认为当您有大量相同的小文件时,这会适得其反。
我决定选择duperemove,它只执行基于文件的重复数据删除。除了 C 构建环境和自动工具之外,您libsqlite3-dev的计算机上还需要该软件包。获取源代码并通过make从源目录运行来构建它们。duperemove然后可以直接从源目录运行,对于那些不想make install在系统上随机运行东西的人来说。
duperemove文档提到了两种运行方法:直接运行,或者通过运行并将其输出传输到. 第一个仅建议用于小数据集。然而,对于我的 2\xe2\x80\x933 TB 数据集和大约 400 万个文件来说,第二个结果非常消耗资源(一天后,进度约为 0.5%,并且内存使用量不断增加)交换使系统几乎无法使用)。duperemovefdupesduperemove
似乎对我有用的是
\nsudo duperemove -drA /foo --hashfile=/path/to/duperemove.hashfile\nRun Code Online (Sandbox Code Playgroud)\n这会:
\n-d),而不是仅仅收集哈希值并输出重复的列表-r)-A需要,因为我的快照是只读的)--hashfile),这给您带来两个优点:\nfdupes尽管哈希文件占用磁盘空间:每个块 90 字节,每个文件 270 字节,但该进程不会占用系统内存(与在模式下运行不同)。duperemove分多个阶段运行:
duperemove只要索引数据库保持不变,就可以随时中断和恢复。
我运行duperemove的磁盘有 8 个子卷,其中 5 个子卷定期创建快照,并保留 24 个快照(最近 12 个每月快照、5 个每周快照和 7 个每日快照)。包括快照在内,该磁盘可容纳约 5\xe2\x80\x936 百万个文件,占用 3.5 TB(去重前,去重后预计为 1.8 TB)。
当duperemove开始运行并显示进度时,该百分比仅指索引阶段,而不是整个重复数据删除过程。加载重复的哈希值可能比这要少得多或多得多,具体取决于检查了多少块。重复数据删除所花费的时间与索引的时间大致相同。此外,索引阶段的进度计算似乎仅基于文件数,而不是块数,如果所有大文件往往位于文件的开头(或结尾),那么它就成为所需总时间/空间的不可靠指标。该集。
索引阶段的资源使用量足够低,足以让我的系统在使用哈希文件时保持响应,尽管加载重复数据可能会占用您的可用内存。如果索引数据库大于系统上的可用内存量,则可能会导致过多的交换并降低系统速度。
\n对所有内容(默认块大小为 128K)进行索引大约需要 28 天才能完成,并生成了 21 GB 的哈希文件。我在第 36 天耗尽了内存,导致我的系统没有响应,所以我不得不中止。四天来,该duperemove进程的内存使用量一直在 12\xe2\x80\x9314 GB 左右波动,但总内存使用量不断增加,直到系统变得不可用。
对于接下来的尝试,我决定逐个删除子卷的重复数据,并在我知道已移动数据的两个子卷的部分之间进行另一次运行。我从 1024K 块大小开始,尽管这会错过较小的重复块以及小于块大小的文件,以换取更好的性能。这花了大约 24 小时,最终在我的驱动器 \xe2\x80\x93 上释放了大约 45 GB 的空间,性能令人满意,但节省的空间没有达到我的预期。
\n我中止了在 300G 子卷 \xe2\x80\x93 上使用 4K 进行的另一次尝试,索引所需的时间大约是 1024K 的四倍,但 3 天后,加载重复哈希值仍然没有完成。另一次 64K 的尝试在 4 小时内完成。请注意,第一遍之后的任何后续传递的重复数据删除应该更快地完成,因为只有小块需要进行重复数据删除。
\n因此,根据实践经验,我的建议是:
\n/tmp可能不是一个好主意,因为它可能会在重新启动时被擦除(即使您不打算重新启动,您可能希望在系统崩溃或断电时保持安全)。