我有一个 3.7TiB 的实时 btrfs 文件系统,已满 90%,包括旧快照和新的 4TB 备份硬盘。如何将所有现有快照复制到备份硬盘?
我试过了
# btrfs send home_1 home_2 home_3 share_1 share_2 share_3 ...
但在传输 2/3 的快照之前备份硬盘已满。所以我做了一些研究:
# ### create test image
# dd bs=1M count=1000 > btrfs_test.dd
# mkfs.btrfs btrfs_test.dd
# ### create snapshots
# btrfs subvol create testvol/
# btrfs subvol snapshot -r testvol/ testvol_0/
# ### (copy some ISO image)
# btrfs subvol snapshot -r testvol/ testvol_1/
# ### (proceed until testvol_3)
然后我的测试文件系统已满 91%,使用了 818MiB。
# btrfs send testvol_* | wc -c
At subvol testvol_0
At subvol testvol_1
At subvol testvol_2
At subvol testvol_3
1466441978 # 1398MiB >> 1000MiB
当简单地用 1 个命令发送所有快照时,数据被复制,并且流的大小以及接收端的快照大小超过了原始使用的空间和硬盘的容量。
所以实际的问题变成了:如何复制多个快照而不复制其中两个或多个快照中包含的数据?
对于这个简单的测试用例,我成功地尝试了增量方法:
# ( btrfs send testvol_0; btrfs send -p testvol_0 testvol_1; btrfs send -p testvol_1 testvol_2; btrfs send -p testvol_2 testvol_3 ) | wc -c
At subvol testvol_0
At subvol testvol_1
At subvol testvol_2
At subvol testvol_3
838778546 # 800 MiB < 1000MiB
但是在真实的文件系统上有多个子卷,每个子卷都有多个快照。我无法定义任何与 一起使用的顺序-p
。如果一个数据块在子卷之间共享home_1
,当然我只想传输和存储一次home_2
。share_3
任何想法如何做到这一点?
TL;DR:使用
-c
顶部描述的参数通常有效。当快照包含硬链接时,Linux 内核中有一个错误会在发送快照时触发错误——有关详细信息,请参阅答案末尾的结论。我正在试验这个
-c
参数,它看起来很有希望:我仍然不确定这是否是我需要的。对此解决方案有何评论?
更新:为了使用我的真实文件系统进行测试,我编写了一个 Perl 脚本来轻松发送一组子卷(创建列表
-c
很快变得乏味)并将一些数据发送到/dev/null
:结果:
btrfs send some-subvolme_* | pv > /dev/null
:24GiB 0:04:17 [95.2MiB/s]perl btrfs-send-all.pl some-subvolume_* | bash | pv > /dev/null
:12.7GiB 0:03:58 [54.7MiB/s]这并没有带来多大的性能提升,但存储空间减少了近 50%!我现在正试图真正运行它……
更新:我成功传输了 2 个快照,但第三个
btrfs receive
失败并显示以下错误消息:命名文件存在于
subvol_2
但尚未subvol_3
存在于.subvol_1
我试图比较发送和接收的快照:
前两个快照似乎被正确传输,但是
subvol_3
是subvol_1
. 这绝对是一个克隆,因为备份磁盘上的已用空间仅为快照总大小的 39% — 由于它们共享大多数文件,因此几乎超过 1/3。为什么
btrfs send subvol_3 -c subvol_1 -c subvol_2 | btrfs receive
没有正确传输快照但克隆subvol_1
然后无法删除应该保留subvol_3
且仅存在于中的文件subvol_2
?更新:会不会是这个错误?https://patchwork.kernel.org/patch/10073969/
我正在使用内核 4.9 运行 Debian 9 Stretch,它似乎比补丁更旧。
更新:因为找不到任何解决方案,我只是复制了每个子卷的最新快照。然后我有大约 500GiB 的可用空间并尝试使用已复制的快照作为
-p
参数添加上一个快照。然后我收到了与上面相同的快照相同的错误消息。结论:我得出结论,我遇到了上面链接的错误。我不得不使用更新的 Linux 内核重新启动这台机器,或者从另一台计算机访问文件系统,但这不可行,因为这是一个生产系统。
到目前为止,我对 btrfs 没有任何问题,但是运行 rsnapshot(它会创建很多硬链接)并发送 btrfs 快照仍然可能在当前的 Debian 稳定版上出现问题。