有没有一种简单的方法可以将 btrfs 子卷移动到不同的 btrfs 文件系统?

有没有一种简单的方法可以将 btrfs 子卷移动到不同的 btrfs 文件系统?

我有两个独立的 btrfs 文件系统,我想对其进行整合。子卷结构如下所示:

/ filesystemA
|- subvolume1
|- subvolume2
|- ...
|- subvolumeN

/ filesystemB
|- subvolume1
|- subvolume2
|- ...
|- subvolumeM

filesystemB是目标。我想将子卷 1 到 N 移动到filesystemB.N超过 1000,因为它们是每日快照子卷 - 也因此它们之间的差异很小,即存在大量共享数据。filesystemA是 1TB,但du路径上的文件总数超过 300TB(驱动器上的实际空间使用量小于 500GB)。

因此,我认为直接mvcpfilesystemAfilesystemB是不可行的,因为它不会意识到 btrfs 子卷或数据的共享性质。

我已经阅读了文档btrfs send几次btrfs receive,看起来这可能有效,本质上是filesystemB增量重建整个子卷结构。但我希望有一种更简单的方法,因为我必须编写脚本(由于子卷数量较多),而且我觉得这可能很容易出错。

(此外,发送/接收要求子卷为只读,而 Ubuntu 14.04 上的 btrfs-tools 版本似乎没有允许btrfs property我将现有子卷设置为只读的命令。我可以安装更高版本,但为了在这台“生产”机器上进行配置管理,不希望这样做。)

答案1

我很确定,您不会绕过 btrfs-send/btrfs-receive。另一种选择是复制子卷,然后在目标上对它们进行重复数据删除,但这需要很长时间。

对于只读问题:由于这些是每日快照,所以大多数卷不是只读的吗?

我会做一个

$btrfs subvolume create /subvolumeA/source
$for i in /filesystemA/subvolume*; do btrfs subvolume snapshot -r $i /filesystemA/source/$i; done

现在您已拥有 /filesystemA/source/ readonly 下的所有子卷。

现在,您可以使用 btrfs-send 和父语句将它们在循环中增量发送到目的地。

如果某些快照应该再次可写,您可以使用 将这些快照的内容复制到新的可写子卷cp --reflink

答案2

我希望你的清单已经找到了。您确定property该版本上的命令没有记录吗?这个答案建议您可以使用类似的命令btrfs property set -ts /path/to/snapshot ro true来纠正问题。

对于未来的读者:将新快照设置为只读,并-r在创建快照时使用参数。我在我的脚本中使用类似的东西:

comm -23 \
    <(btrfs subvolume list -ors --sort=path /fsA/ | perl -ne 'print if s/.+?\spath\s+(.+)/\1/') \
    <(btrfs subvolume list -ors --sort=path /fsB/ | perl -ne 'print if s/.+?\spath\s+(.+)/\1/')

这应该提供文件系统上的只读快照卷的列表A哪个是不是在文件系统上。您可以迭代该列表,对每个列表进行发送/接收以进行同步。

相关内容