![从 btrfs 快照中删除文件并仍然使用 btrfs 发送/接收?](https://linux22.com/image/636957/%E4%BB%8E%20btrfs%20%E5%BF%AB%E7%85%A7%E4%B8%AD%E5%88%A0%E9%99%A4%E6%96%87%E4%BB%B6%E5%B9%B6%E4%BB%8D%E7%84%B6%E4%BD%BF%E7%94%A8%20btrfs%20%E5%8F%91%E9%80%81%2F%E6%8E%A5%E6%94%B6%EF%BC%9F.png)
我计划使用 btrfs 发送/接收来同步两个文件系统并在备份上保留一些旧快照(如时间机器)。
现在,如果用户要求我从所有备份快照中删除一个文件或目录,因为它包含敏感数据,会发生什么?
我担心这样做无法实现发送/接收功能。对吗?
答案1
这确实是可能的(至少在我的实验中,它有效)。
首先删除侧面的文件send
,拍摄快照,然后send
使用receive
可用于增量更新的任何现有快照进行增量更新。
现在,您将在远程端获得一个不包含相关文件的快照,并且您可以将其用于所有未来備份。
最后一件事是从所有老的快照。重要的是不要触碰你刚刚发送的快照,因为文件已经删除- 因为您需要保持不变,以便将其用作将来备份的父级。
因此,对于接收端的每个旧快照,使其可写,删除文件,然后(可选)再次使其只读。
以下是显示两个虚拟 btrfs 文件系统映像上进程的完整命令集:
set -x
echo "Make two btrfs images for our test"
dd if=/dev/zero bs=1M count=512 of=/tmp/img1.img
dd if=/dev/zero bs=1M count=512 of=/tmp/img2.img
losetup -f /tmp/img1.img
losetup -f /tmp/img2.img
mkfs.btrfs --mixed /dev/loop0
mkfs.btrfs --mixed /dev/loop1
echo "Mount them"
mkdir /tmp/sender /tmp/receiver
mount -t btrfs /dev/loop0 /tmp/sender
mount -t btrfs /dev/loop1 /tmp/receiver
btrfs subvolume create /tmp/sender/test
mkdir /tmp/sender/snaps
mkdir /tmp/receiver/snaps
echo "Create a 1 MB file, this is what we'll delete in the future"
dd if=/dev/urandom bs=1M count=1 of=/tmp/sender/test/f1
echo "Take our first snapshot, and send it"
btrfs subvolume snapshot -r /tmp/sender/test /tmp/sender/snaps/snap1
sync
btrfs send /tmp/sender/snaps/snap1 | btrfs receive /tmp/receiver/snaps
echo "Create a 2 MB file, snapshot, send and receive, using snap1 as parent"
dd if=/dev/urandom bs=2M count=1 of=/tmp/sender/test/f2
btrfs subvolume snapshot -r /tmp/sender/test /tmp/sender/snaps/snap2
sync
btrfs send -p /tmp/sender/snaps/snap1 /tmp/sender/snaps/snap2 | btrfs receive /tmp/receiver/snaps
echo "Now we can delete snap1 on the sender."
btrfs subvolume delete /tmp/sender/snaps/snap1
echo "Create a 3 MB file, snapshot send and receive, using snap2 as parent"
dd if=/dev/urandom bs=3M count=1 of=/tmp/sender/test/f3
btrfs subvolume snapshot -r /tmp/sender/test /tmp/sender/snaps/snap3
sync
btrfs send -p /tmp/sender/snaps/snap2 /tmp/sender/snaps/snap3 | btrfs receive /tmp/receiver/snaps
echo "Now we can delete snap2 on the sender."
btrfs subvolume delete /tmp/sender/snaps/snap2
echo "Delete the file we don't want anymore on the sender"
rm /tmp/sender/test/f1
echo "Snapshot, and send the deletion"
btrfs subvolume snapshot -r /tmp/sender/test /tmp/sender/snaps/snap4
btrfs send -p /tmp/sender/snaps/snap3 /tmp/sender/snaps/snap4 | btrfs receive /tmp/receiver/snaps
echo "Now we can delete snap3 on the sender - this will remove all reference to f1 on the sender"
btrfs subvolume delete /tmp/sender/snaps/snap3
echo "Confirm filesystem usage"
sync
btrfs filesystem du /tmp/sender/snaps/*
btrfs filesystem du /tmp/receiver/snaps/*
echo "Then, we can go and clean up the file in all backups on the receiver"
btrfs property set -t s /tmp/receiver/snaps/snap1 ro false
rm /tmp/receiver/snaps/snap1/f1
btrfs property set -t s /tmp/receiver/snaps/snap1 ro true
btrfs property set -t s /tmp/receiver/snaps/snap2 ro false
rm /tmp/receiver/snaps/snap2/f1
btrfs property set -t s /tmp/receiver/snaps/snap2 ro true
btrfs property set -t s /tmp/receiver/snaps/snap3 ro false
rm /tmp/receiver/snaps/snap3/f1
btrfs property set -t s /tmp/receiver/snaps/snap3 ro true
echo "Lastly, make sure incremental backups are still working against snap4"
echo "Create a 5 MB file, snapshot send and receive, using snap4 as parent"
dd if=/dev/urandom bs=5M count=1 of=/tmp/sender/test/f5
btrfs subvolume snapshot -r /tmp/sender/test /tmp/sender/snaps/snap5
sync
btrfs send -p /tmp/sender/snaps/snap4 /tmp/sender/snaps/snap5 | btrfs receive /tmp/receiver/snaps
echo "And see that usage is as we expect - all references to the 1MB file are gone."
sync
btrfs filesystem du /tmp/sender/snaps/*
btrfs filesystem du /tmp/receiver/snaps/*
echo "Clean up"
umount /tmp/sender /tmp/receiver
losetup -d /dev/loop0 /dev/loop1
rm /tmp/img1.img /tmp/img2.img