btrfs 接收增量流失败:“文件存在”

btrfs 接收增量流失败:“文件存在”

对于 btrfs 子卷,我有从两个阶段创建的简单增量备份:

btrfs send old/@ > base.btrfs
btrfs send new/@ -p old/@ > update.btrfs

两个源子卷是在不同时间从同一活动安装的子卷捕获的快照。

在目标上,我尝试恢复:

btrfs receive ./ < base.btrfs
btrfs receive ./ < update.btrfs

预期是,前一个命令将创建初始备份阶段的恢复快照,而后者将应用进一步的增量阶段。

前一个命令成功,但后一个命令失败:

ERROR: creating snapshot ./@ -> @ failed: File exists

由于很明显我无法将后一阶段有效地应用于不存在的目标,因此我很困惑为什么该过程会执行此检查,以及预期成功应用更新的原因。

如何将更新阶段应用到恢复初始阶段生成的目标中?

答案1

您不能拥有(如在发送方)多个同名的子卷。

您可以mv在目标系统上获取基本快照/子卷:

mv @ @.old
btrfs receive ./ < update.btrfs

答案2

自从发布这个问题以来,我已经学到了足够的知识来回答这个问题。

答案分为两部分。

首先,receive无论新子卷是从子流还是父流创建的,子命令始终会在目标目录中创建一个与原始子卷同名的新条目。因此,目标目录必须为空,至少应具有与原始子卷相同的名称。一种简单的方法是为父子卷和每个子子卷分别创建一个新的空目录。

其次,尽管对子命令的调用不会引用父命令,但只要父命令已恢复到同一分区的子卷,它就可以利用父命令中的必要数据。也就是说,只要先前在父命令的同一分区上调用过子命令,receive子命令就会对子流产生所需的效果。

一旦父母和孩子被恢复,任何父母都可以被删除而不会损害孩子。

因此,以下将是实现原始目标的有效命令序列:

mkdir _tmp
btrfs receive _tmp/ < base.btrfs
btrfs receive ./ < update.btrfs
btrfs subvolume delete _tmp/@
rmdir _tmp

然后子流的全部内容将可通过 获得./@

base.btrfs当然,如果要保存的子流有多个祖先(例如,有自己的父流),则需要进一步的命令。

相关内容