如何使用子卷恢复家庭根分区的 btrfs 快照备份

如何使用子卷恢复家庭根分区的 btrfs 快照备份

我在物理 SSD 驱动器上安装了 btrfs、luks 和 lvm。我用 apt 做了一些乱七八糟的事情,破坏了我的系统。我想将其恢复到以前的状态。

当我在实时 USB 上启动并解密我的 luks 驱动器并挂载 btrfs 分区时,我得到了以下内容

# btrfs subvolume list ./ (when in my luks drive) :
ID 256 gen 202072 top level 5 path @
ID 257 gen 202063 top level 256 path @/home
ID 258 gen 202063 top level 256 path @/var
ID 259 gen 202072 top level 256 path @/.snapshots
ID 271 gen 185 top level 259 path @/.snapshots/12/snapshot
[...]
ID 1739 gen 202073 top level 259 path @/.snapshots/1480/snapshot
[...]

我想恢复 ID 1739 的快照@重新启动我的系统并将其 /home 和 /var 挂载在其中。

我怎样才能做到这一点 ?(我读过一些 btrfs 文档和一些在线资料,但没有一个符合我的要求)

我不明白恢复是否是个好选择,或者我是否应该使用 btrfs 发送/接收或 btrfs 子快照。恢复需要卸载分区,但我不明白它等待什么目标。如果我移动@到已安装的 btrfs 根目录breaked_@并在其中运行btrfs sub snapshot breaked_@/.snapshots/1480/snapshot/ @,它会为我创建一个@没有 .snapshots 子文件夹也@/home没有@/var。我该怎么办?

btrfs restore -D -t 1480 /dev/disk/by-uuid/ede[...] ./@当然不起作用,或者因为它已安装,或者因为当它未安装时,./@ 不存在。在这种情况下,它会以这种方式失败:

ERROR: tree block bytenr 1480 is not aligned to sectosize 4096
couldn't read tree root
could no open root, trying backup super

如果我尝试使用 1739 而不是 1480,结果也是一样。

(我也尝试过使用时间移位,但是使用 luks 加密驱动器,它什么都不懂)。

在 BTRFS 中将根从一个子卷移动到另一个子卷是我发现的最接近的案例,但如果我复制快照内容,它将被添加到已有的内容中@,如果我@在复制之前删除,我担心会删除所有快照。

这个问题类似于系统更新失败后如何回滚 root 的 btrfs 快照 [ / ]因此,任何一方的答案都可能解决这两个问题。但两年来一直没有回复,我发布了我的回复,并附上了它的具体性和额外的细节。我希望在社区中能有更多好运。我也把它发布在github btrfs-progs存储库发行系统。

为了更好地理解所有这些应该如何工作,这里是崩溃系统的 /etc/fstab(在 btrfs 根分区内):

/dev/mapper/vgmint-root   /           btrfs   subvolid=256,subvol=/@,rw,relatime,compress=lzo,ssd,space_cache=v2   0 0
# /boot was on /dev/nvme0n1p2 during installation
UUID=f4ea[...]            /boot       ext4   defaults   0 2
# /boot/efi was on /dev/nvme0n1p1 during installation
UUID=4773-82E0            /boot/efi   vfat   umask=0077 0 1
/dev/mapper/vgmint-swap   1 none      swap   sw         0 0

btrfs subvolume list /mnt/完整结果:

ID 256 gen 202080 top level 5 path @
ID 257 gen 202080 top level 256 path @/home
ID 258 gen 202080 top level 256 path @/var
ID 259 gen 202072 top level 256 path @/.snapshots
ID 271 gen 185 top level 259 path @/.snapshots/12/snapshot
ID 669 gen 32079 top level 259 path @/.snapshots/410/snapshot
ID 1103 gen 82780 top level 259 path @/.snapshots/844/snapshot
ID 1104 gen 82781 top level 259 path @/.snapshots/845/snapshot
ID 1125 gen 84805 top level 259 path @/.snapshots/866/snapshot
ID 1180 gen 95864 top level 259 path @/.snapshots/921/snapshot
ID 1357 gen 142396 top level 259 path @/.snapshots/1098/snapshot
ID 1358 gen 142498 top level 259 path @/.snapshots/1099/snapshot
ID 1384 gen 146456 top level 259 path @/.snapshots/1125/snapshot
ID 1400 gen 147708 top level 259 path @/.snapshots/1141/snapshot
ID 1467 gen 155992 top level 259 path @/.snapshots/1208/snapshot
ID 1468 gen 156011 top level 259 path @/.snapshots/1209/snapshot
ID 1476 gen 156421 top level 259 path @/.snapshots/1217/snapshot
ID 1477 gen 156423 top level 259 path @/.snapshots/1218/snapshot
ID 1508 gen 160880 top level 259 path @/.snapshots/1249/snapshot
ID 1522 gen 162353 top level 259 path @/.snapshots/1263/snapshot
ID 1564 gen 171472 top level 259 path @/.snapshots/1305/snapshot
ID 1588 gen 176804 top level 259 path @/.snapshots/1329/snapshot
ID 1612 gen 182891 top level 259 path @/.snapshots/1353/snapshot
ID 1625 gen 184737 top level 259 path @/.snapshots/1366/snapshot
ID 1626 gen 184738 top level 259 path @/.snapshots/1367/snapshot
ID 1627 gen 184744 top level 259 path @/.snapshots/1368/snapshot
ID 1628 gen 184747 top level 259 path @/.snapshots/1369/snapshot
ID 1629 gen 184755 top level 259 path @/.snapshots/1370/snapshot
ID 1630 gen 184757 top level 259 path @/.snapshots/1371/snapshot
ID 1631 gen 184765 top level 259 path @/.snapshots/1372/snapshot
ID 1632 gen 184767 top level 259 path @/.snapshots/1373/snapshot
ID 1633 gen 184785 top level 259 path @/.snapshots/1374/snapshot
ID 1634 gen 184786 top level 259 path @/.snapshots/1375/snapshot
ID 1635 gen 184809 top level 259 path @/.snapshots/1376/snapshot
ID 1637 gen 184872 top level 259 path @/.snapshots/1378/snapshot
ID 1638 gen 184909 top level 259 path @/.snapshots/1379/snapshot
ID 1639 gen 184910 top level 259 path @/.snapshots/1380/snapshot
ID 1643 gen 185306 top level 259 path @/.snapshots/1384/snapshot
ID 1644 gen 185307 top level 259 path @/.snapshots/1385/snapshot
ID 1645 gen 185310 top level 259 path @/.snapshots/1386/snapshot
ID 1646 gen 185314 top level 259 path @/.snapshots/1387/snapshot
ID 1647 gen 185315 top level 259 path @/.snapshots/1388/snapshot
ID 1648 gen 185317 top level 259 path @/.snapshots/1389/snapshot
ID 1651 gen 185646 top level 259 path @/.snapshots/1392/snapshot
ID 1665 gen 187383 top level 259 path @/.snapshots/1406/snapshot
ID 1682 gen 189636 top level 259 path @/.snapshots/1423/snapshot
ID 1706 gen 192710 top level 259 path @/.snapshots/1447/snapshot
ID 1720 gen 194266 top level 259 path @/.snapshots/1461/snapshot
ID 1736 gen 196318 top level 259 path @/.snapshots/1477/snapshot
ID 1739 gen 202073 top level 259 path @/.snapshots/1480/snapshot
ID 1740 gen 196753 top level 259 path @/.snapshots/1481/snapshot
ID 1741 gen 196775 top level 259 path @/.snapshots/1482/snapshot
ID 1742 gen 196784 top level 259 path @/.snapshots/1483/snapshot
ID 1743 gen 196862 top level 259 path @/.snapshots/1484/snapshot
ID 1744 gen 196866 top level 259 path @/.snapshots/1485/snapshot
ID 1745 gen 196868 top level 259 path @/.snapshots/1486/snapshot
ID 1746 gen 196869 top level 259 path @/.snapshots/1487/snapshot
ID 1747 gen 196878 top level 259 path @/.snapshots/1488/snapshot
ID 1748 gen 196886 top level 259 path @/.snapshots/1489/snapshot
ID 1749 gen 196901 top level 259 path @/.snapshots/1490/snapshot
ID 1750 gen 196902 top level 259 path @/.snapshots/1491/snapshot
ID 1778 gen 199404 top level 259 path @/.snapshots/1519/snapshot
ID 1791 gen 200900 top level 259 path @/.snapshots/1532/snapshot
ID 1792 gen 201015 top level 259 path @/.snapshots/1533/snapshot
ID 1793 gen 201131 top level 259 path @/.snapshots/1534/snapshot
ID 1794 gen 201246 top level 259 path @/.snapshots/1535/snapshot
ID 1795 gen 201361 top level 259 path @/.snapshots/1536/snapshot
ID 1796 gen 201476 top level 259 path @/.snapshots/1537/snapshot
ID 1797 gen 201591 top level 259 path @/.snapshots/1538/snapshot
ID 1798 gen 201706 top level 259 path @/.snapshots/1539/snapshot
ID 1799 gen 201821 top level 259 path @/.snapshots/1540/snapshot
ID 1800 gen 201936 top level 259 path @/.snapshots/1541/snapshot
ID 1801 gen 202051 top level 259 path @/.snapshots/1542/snapshot
ID 1802 gen 202079 top level 5 path tmp_@

tmp_@ 是我之前尝试恢复系统的结果。我可能可以删除它。(它没有填充 /home 和 /var)。

答案1

btrfs restore、、btrfs send都是btrfs receive错误的命令。首先你需要了解的是,所有快照默认都是只读子卷。只有当前活动的“快照”(默认子卷)才标记为可写。因此,你需要做的是将默认子卷更改为所需快照的子卷,使所需快照的子卷可写,并删除所有“较新”/“较年轻”的快照以防止出现问题。

重要提示:快照 ID 不等于子卷 ID,本教程未经测试

另一个提示:通常情况下,你会使用 linux 程序鲷鱼回滚到以前的快照,但我个人对这个程序的体验不太好,但你应该尝试一下,但在这里,首先备份你的数据

  1. 对整个 BTRFS 卷进行完整备份(强烈推荐)
  2. 使用以下命令从另一个操作系统挂载你的 BTRFS 文件系统mount --options subvolid=5,noatime /dev/mapper/lvm/encrypted_btrfs /mnt/(你需要更改/dev/mapper/lvm/encrypted_btrfs为你的实际路径)
  3. 使用命令获取默认子卷btrfs subvolume get-default /mnt/并记住当前默认子卷的 ID 和路径(在我的系统上,默认子卷 ID 是259,路径是@/.snapshots/1/snapshot
  4. 让我们为d默认s子卷小路作为DSPATH=$(btrfs subvolume get-default /mnt/ | cut --delimiter=@ --fields=2)
  5. 使用 仔细检查当前默认子卷的 ro 标志btrfs property get -ts /mnt/@$DSPATH,它应该打印ro=false
  6. 让我们为你的未来命名另一个变量新的 d默认s子卷小路作为NEWDSPATH=$(btrfs subvolume list /mnt/ | grep -F "ID 1739" | cut --delimiter=@ --fields=2)
  7. 再次检查 ro 标志,但这次是你未来新的默认子卷btrfs property get -ts /mnt/@$NEWDSPATH,它应该打印ro=true
  8. 暂时将 BTRFS-ROOT 子卷设为您的默认子卷btrfs subvolume set-default 5 /mnt/(ID 为 5 的子卷始终是 BTRFS-ROOT 子卷)
  9. 删除所有较新/较新的“快照”子卷(快照号大于所需快照),btrfs subvolume delete /mnt/@/.snapshots/GREATER-THAN-1480/snapshot并删除以前的默认子卷btrfs subvolume delete /mnt/@$DSPATH
  10. 使你的未来新的默认子卷可写入btrfs property set -ts /mnt/@$NEWDSPATH ro false
  11. 现在真正让你未来的新默认子卷成为默认子卷btrfs subvolume set-default 1739 /mnt/
  12. 卸载umount /mnt,重新启动原来的操作系统,并祈祷它能正常工作

提示:可能需要将快照目录重命名为存储新默认子卷的目录的名称和/或编辑某些 snapper 配置文件,否则 snapper(管理快照的 Linux 程序)可能会出错,因为它找不到某些快照。如果您运气不好,这也可能会导致系统启动错误,从而阻止系统启动。

相关内容