Btrfs 文件系统快照的创建与恢复

btrfs 命令介绍、快照的创建与恢复

安装必要软件

1
pacman -Sy btrfs-progs

btrfs 常用命令

挂载

btrfs 有个默认子卷,如果不加挂载参数,直接 mount 一个 btrfs 文件系统时挂载出来的是它的默认子卷,而不一定是根,所以可以加 subvol=/ 参数来挂载根, compress=zstd 表示启用透明压缩(根据实际添加),如下:

1
mount -t btrfs -o subvol=/,compress=zstd /dev/nvme1n1p4 /mnt

查看子卷

查看 btrfs 子卷, -u 表示显示 uuid ,/mnt 挂载目录(无论挂载的是“根”还是“某个子卷”都可以使用此命令查看全部子卷),如下:

1
2
3
4
5
6
7
$ btrfs subvolume list -u /mnt
ID 275 gen 25505 top level 5 uuid 2ae825dd-d569-7c49-bc8e-6ebdb74aee20 path timeshift-btrfs/snapshots/2022-07-30_07-41-33/@
ID 276 gen 25505 top level 5 uuid 2f991131-f60b-5c47-bb97-24e6146637f6 path timeshift-btrfs/snapshots/2022-07-30_07-41-33/@home
ID 299 gen 25498 top level 5 uuid d7b2a91e-9517-324a-a2a5-08564bf8c9e2 path timeshift-btrfs/snapshots/2022-08-01_10-08-31/@
ID 300 gen 25498 top level 5 uuid 5888c7db-7cf5-2041-9c66-4de5b78635dc path timeshift-btrfs/snapshots/2022-08-01_10-08-31/@home
ID 304 gen 25593 top level 5 uuid 3a758ddd-dc03-4a41-bbc8-dc4fe50ed5c7 path @
ID 305 gen 25593 top level 5 uuid 418632cd-bce0-304d-aa6d-9110a606917a path @home

创建子卷

1
btrfs subvolume create /mnt/zijuan2

删除子卷

1
btrfs subvolume delete /mnt/zijuan2

创建快照

必做工作 (仅适用于 Arch Linux)

因为 btrfs 无法对挂载了其他设备的文件夹进行快照,例如 /boot/efi 目录就挂载了efi分区,如果系统更新内核后会影响到该目录,而使用快照恢复后就会导致无法启动系统。解决办法是创建一个文件,该文件会在 pacman 更新内核后对 boot 目录进行备份到 .bootbackup 目录下,文件 /etc/pacman.d/hooks/95-bootbackup.hook 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
[Trigger]
Operation = Upgrade
Operation = Install
Operation = Remove
Type = Path
Target = usr/lib/modules/*/vmlinuz

[Action]
Depends = rsync
Description = Backing up /boot...
When = PostTransaction
Exec = /usr/bin/rsync -a --delete --checksum /boot /.bootbackup

如果使用快照恢复系统后无法启动时,使用 archiso live 系统内进行如下操作即可:

1
2
3
mount /dev/nvme1n1p2 /boot/efi    # 挂载efi分区
rm -rf /boot/* # 删除boot内容
cp -af /.bootbackup/boot/* /boot # 复制备份的boot内容

创建快照

所谓的创建快照就是对 btrfs 文件系统中的子卷创建快照,创建的快照其实是个子卷。
查看子卷命令:

1
2
3
$ btrfs subvolume list -u /mnt
ID 304 gen 25593 top level 5 uuid 3a758ddd-dc03-4a41-bbc8-dc4fe50ed5c7 path @
ID 305 gen 25593 top level 5 uuid 418632cd-bce0-304d-aa6d-9110a606917a path @home

/mnt/@ 子卷创建快照,名字为 /mnt/@snapshot,示例如下:

1
btrfs subvolume snapshot /mnt/@ /mnt/@snapshot

/mnt/@home 子卷创建快照,名字为 /mnt/@homesnapshot,示例如下:

1
btrfs subvolume snapshot /mnt/@home /mnt/@homesnapshot

查看子卷:

1
2
3
4
5
$ btrfs subvolume list -u /mnt
ID 304 gen 25593 top level 5 uuid 3a758ddd-dc03-4a41-bbc8-dc4fe50ed5c7 path @
ID 305 gen 25593 top level 5 uuid 418632cd-bce0-304d-aa6d-9110a606917a path @home
ID 306 gen 25593 top level 5 uuid 3a758ddd-dc03-4a41-bbc8-dc4abc1055c7 path @snapshot
ID 307 gen 25593 top level 5 uuid 418632cd-bce0-304d-aa6d-9110a127817a path @homesnapshot

恢复快照

如果恢复的系统已经被挂载启动,就需要使用 Live 系统对快照进行恢复。

按照上面的方法创建快照后,当需要恢复 @@home 这两个子卷的快照时,分为如下几步:

  1. 创建当前 @@home 这两个子卷的快照,分别命名为 @before@homebefore ,以防万一恢复失败时可以补救,为了防止浪费空间恢复成功后可手动删除。
  2. 删除 @@home 这两个子卷。
  3. 将需要恢复的 @snapshot@homesnapshot 分别创建名为 @@home 的快照即可。
  4. 重启系统。
  5. 如果恢复成功,可以手动删除 @before@homebefore 这两个子卷。

实际操作步骤如下: (带有 $ 符号的行表示要执行的命令)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
## 1. 备份原来的子卷
$ btrfs subvolume snapshot /mnt/@ /mnt/@before
Create a snapshot of '/mnt/@' in '/mnt/@before'

$ btrfs subvolume snapshot /mnt/@home /mnt/@homebefore
Create a snapshot of '/mnt/@home' in '/mnt/@homebefore'

## 2. 删除原来的子卷
$ btrfs subvolume delete /mnt/@
Delete subvolume (no-commit): '/mnt/@'

$ btrfs subvolume delete /mnt/@home
Delete subvolume (no-commit): '/mnt/@home'

## 3. 对需要恢复的快照再次创建快照分别名为@ @home
$ btrfs subvolume snapshot /mnt/@snapshot /mnt/@
Create a snapshot of '/mnt/@snapshot' in '/mnt/@'

$ btrfs subvolume snapshot /mnt/@homesnapshot /mnt/@home
Create a snapshot of '/mnt/@homesnapshot' in '/mnt/@home'

## 4. 重启系统
$ reboot

## 5. 如果恢复成功,可手动删除备份的子卷
$ btrfs subvolume delete /mnt/@before
Delete subvolume (no-commit): '/mnt/@before'

$ btrfs subvolume delete /mnt/@homebefore
Delete subvolume (no-commit): '/mnt/@homebefore'

使用 timeshift 进行备份与恢复

此处仅介绍命令行的操作方式,首先安装必要软件:

1
pacman -Sy timeshift btrfs-progs

切换为 btrfs 模式,同时会自动生成配置文件:

1
timeshift --btrfs

打开配置文件vim /etc/timeshift/timeshift.json,下面是其中主要项目说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"backup_device_uuid" : "a99599f4-3acd-4c8d-8f7e-82a5df35b22e", // 可使用 sudo blkid 命令查看对应分区UUID
"parent_device_uuid" : "",
"do_first_run" : "false",
"btrfs_mode" : "true", // 确认是 true
"include_btrfs_home_for_backup" : "true", // 备份是否包括home目录
"include_btrfs_home_for_restore" : "true", // 恢复是否包换home目录
"stop_cron_emails" : "true",
"schedule_monthly" : "false", // 修改为 false
"schedule_weekly" : "false", // 修改为 false
"schedule_daily" : "false", // 修改为 false
"schedule_hourly" : "false", // 修改为 false
"schedule_boot" : "false", // 修改为 false
"count_monthly" : "2",
"count_weekly" : "3",
"count_daily" : "5",
"count_hourly" : "6",
"count_boot" : "5",
"snapshot_size" : "0",
"snapshot_count" : "0",
"date_format" : "%Y-%m-%d %H:%M:%S",
"exclude" : [],
"exclude-apps" : []
}

备份

1
timeshift --create --comments "shuo ming"

恢复

1
timeshift --restore