GitHub
logo SHORiNのARCH
快照和系统维护

快照和系统维护

目录

现在我们已经完成了安装桌面环境前的所有准备工作,接下来进行快照的配置,再学习一些简单的日用口诀。

使用 Linux 时我们常常会尝试新东西,加之 Arch 更新策略比较激进,如果不了解一下系统维护的话指不定哪天系统就挂了。而快照可以在你尝试新东西前保存系统状态,方便试完后回档,也可以定时创建快照以防某天系统突然挂掉。

Snapper

OpenSUSE 开发的快照软件,超级好用。

  1. 安装

    sudo pacman -S snapper btrfs-assistant grub-btrfs inotify-tools
    

    snapper 是主程序;

    btrfs-assistant 是 GUI(图形化交互界面),同时提供了几个简单的命令,进一步简化快照回档需要的操作。我们还没有安装桌面环境,但是肯定会用到,先装上。

    grub-btrfs inotify-tools 在创建快照的时候自动在 GRUB 菜单里添加快照启动项。

    可选:snap-pac 利用钩子在进行 pacman 命令的时候自动创建快照。

  2. 重启电脑用新的 initramfs 进入系统

    reboot
    
  3. 激活快照启动项服务

    sudo systemctl enable --now grub-btrfsd
    

    如果你是通过 /efi/grub/grub.cfg 存根读取 /boot/grub/grub.cfg 的方式配置的 GRUB 引导,需要进行额外操作,看:附录:Grub在btrfs文件系统的最佳配置方法

  4. 创建快照配置

    sudo snapper -c root create-config /
    

    -c root 指定要使用的配置,由于该配置不存在,所以 create-config 创建,快照范围是 /

    然后用同样的方式创建 home 的配置:

    sudo snapper -c home create-config /home
    
  5. 设置合理的快照策略

    • 获取当前设置

      sudo snapper -c root get-config
      
    • 修改设置

      可以使用 set-config <配置项> 设置,但是一个个调太麻烦了,建议直接编辑文件。

      sudo vim /etc/snapper/configs/root
      

      以下是我的设置:

      ALLOW_GROUPS="wheel" 允许 wheel 组的用户无须 sudo 就可以操作快照。

      NUMBER_LIMIT="10" 设置最多保存 10 个快照,超出后会按照时间顺序删除旧快照。

      TIMELINE_LIMIT_HOURLY="3" 每隔一小时创建的快照保存 3 个。

      TIMELINE_LIMIT_DAILY="1" 每日快照保存 1 个。

      其他的 TIMELINE_LIMIT 数量都设置为 0。这样就仅保存三个小时前的状态和昨天的状态。

      接着对 home 的快照配置进行一样的修改。

      sudo vim /etc/snapper/configs/home
      
  6. 开启按时间自动创建快照和自动清理

    sudo systemctl enable --now snapper-timeline.timer
    sudo systemctl enable --now snapper-cleanup.timer
    
  7. 创建快照

    分别创建 home 和 root 的快照。

    snapper -c root create -d "before desktop"
    snapper -c home create -d "before desktop"
    

    create 创建快照,-d (description) 添加自定义描述。我们这里是安装桌面之前,所以描述为 before desktop。

  8. 生成 GRUB 菜单入口

    要至少运行一次 grub-mkconfig 生成 GRUB 菜单的快照启动项入口:

    sudo grub-mkconfig -o /boot/grub/grub.cfg
    

现在你学会了快照的创建方法,后续阅读时自行判断要不要创建快照。

回档方法

  • btrfs-assistant 命令行(推荐)

    1. 切换至 root

      以普通用户 sudo 运行可能会出现环境问题,建议切换到 root。

      su -
      
    2. 确认要使用的快照的 snapper 序号

      snapper -c root list
      

      可以使用 grep 筛选快照。

      snapper -c root list | grep "Before"
      

      假设我要用的快照的 snapper 序号是 11

    3. 用 snapper 序号找到对应的 btrfs-assistant 序号

      btrfs-assistant -l
      

      在下图这个例子中,snapper 序号为 11 的 root 快照对应着 btrfs-assistant 的序号 1

      注意一个细节,这条命令会把 home 和 root 的快照排在同一个列表里。图中 snapper 序号为 11 的 home 快照对应着 btrfs-assistant 序号 6

    4. 回档

      btrfs-assistant -r 1
      

      这里的数字是要使用的快照的 btrfs-assistant 序号

  • btrfs-assistant 图形界面

    此时还没有安装桌面环境,你可以后续回来看

    如果你要从命令行打开 btrfs-assistant,必须使用 btrfs-assistant-launcher,仅使用 btrfs-assistant 命令的话不会调用 polkit 提权。

    1. 创建配置

      打开 btrfs assistant,切换到 snapper settings 页面。我们创建子卷的时候至少创建了一个 @ 子卷和一个 @home 子卷,所以需要两个 config(配置)

      • root 根目录快照

        点击 new config 新建配置,config namerootbackup path 选择 /,然后点击 save 保存。

        接着进行一些按照时间自动生成快照的设置。systemd unit settings 里面有三个服务。timeline 是按照时间计划自动创建快照;cleanup 是快照数量达到 number 设定的数量上限之后自动清理快照;boot 是每次开机自动创建快照。按需设置,设置完记得点 apply

      • home 目录快照

        按照同样的方法创建一个 home 目录的配置。

    2. 创建快照

      snapper 页面,select config 选择配置,要创建 root 子卷的快照就选择刚刚创建的名为 root 的配置。点击 new 创建快照,description 是快照的自定义文字描述(注释)。

    3. 使用快照进行恢复

      snapper 页面 --> Browse/restore 页面

      select target 选择想恢复的子卷,再选择想使用的快照,点击 restore,此时会自动帮你创建一个额外的子卷用来备份当前的数据然后弹出一个确认窗口让你填写这个子卷的名字(可以空着不填写)。

    4. 使用快照进行全盘恢复

      因为 @ 子卷和 @home 子卷在创建的时候是平级的,所以虽然 root 目录包含了 home 目录,但是创建 @ 子卷的快照时不会包含 @home 子卷里的内容。这样的子卷布局叫作 扁平布局。因此,需要分别创建 @@home 的快照,然后分别恢复。

  • 从 GRUB 菜单的快照启动项进入系统

    通常在系统完全无法正常登入时使用,进入后用 btrfs-assistant 回档,GUI 或者命令行都可以,方法同上。

遇到异常

从快照启动项进入系统后 snapper list 没能列出快照

因为现在处在快照子卷里而不是原本的 @ 子卷里。之前创建的快照都在 @ 子卷里,挂载之后才能读取到。

  1. 确认根分区设备名

    回忆一下手动安装 Arch 时的挂载操作

    lsblk -p
    

    或者

    findmnt /
    
  2. 挂载根

    mount -t btrfs /dev/nvme0n1p2 /mnt
    

    此时 /mnt 对应的是 /cd 进入 /mnt 会看到系统的 @。也可以选择加上 -o subvol=/@ 挂载 /@ 而不是 /,这种情况下 /mnt 对应的是 @

  3. 指定根进行读取

    我们的子卷存放在 @ 里面,列出快照时指定读取 @

    snapper --no-dbus --root /mnt/@ -c root list
    

    --root 选项指定根,此选项只能在 --no-dbus 下生效。

    可以使用 grep 筛选自己需要的快照:

    snapper --no-dbus --root /mnt/@ -c root list | grep "Before Desktop Environments"
    

    记住快照序号,使用 btrfs-assistant 的命令行工具回档即可,方法上面已经介绍了。

无法从快照启动项进入系统

很大概率是因为快照是只读的导致显示管理器无法正常运行,你的启动日志会卡在 Graphical ....。

  • 解决方法一:切换到别的 TTY 用命令行恢复

    Ctrl+Alt+F2~F8 切换到非图形界面的 TTY,用命令行进行恢复。恢复完成后可以把显示管理器换掉,已知 sddm 会出现此问题而 plasmalogin 不会。

  • 解决方法二:让快照可读(不推荐)

    需要确认 initramfs 类型。

    grep "^HOOKS" /etc/mkinitcpio.conf
    

    这条命令 grep 筛选出文件中由 HOOKS 开头的行。

    确认 HOOKS=(...) 里是 systemd 还是 udev

    • 如果是 systemd

      `grub-btrfsd` 没有提供 systemd 单元,不能用此方法。
      
    • 如果是 udev

      可以设置 overlayfs 让快照可读。

      1. 设置覆盖文件系统(overlayfs)

        设置一个 overlayfs 在内存中创建一个临时可写的类似 live-cd 的环境,否则可能无法正常从快照启动项进入系统。

      2. 编辑 /etc/mkinitcpio.conf

        sudo vim /etc/mkinitcpio.conf
        
      3. 在 HOOKS 里添加 grub-btrfs-overlayfs

        HOOKS= ( ...... grub-btrfs-overlayfs )
        
      4. 重新生成 initramfs

        sudo mkinitcpio -P
        
      5. 重启电脑

拓展内容:手动快照回档

如果以上内容都没能让你正常回档,还可以使用 btrfs 命令手动回档。
  1. 确认根分区设备名

    findmnt /
    

    输出类似:

    TARGET SOURCE          FSTYPE OPTIONS
    /      /dev/nvme0n1p2[/@]
                         btrfs  rw,relatime,compress=zstd:3,ssd,discard=async,space_cache=v2,subvolid=256,
    

    /dev/nvme0n1p2 是我的根分区。

  2. 挂载顶级卷

    我们运行的系统是在子卷里面的。想对子卷进行操作,要先挂载 /

    sudo mount -t btrfs -o subvolid=5 /dev/nvme0n1p2 /mnt
    

    subvolid=5 指定顶级卷;/dev/nvme0n1p2 更换为你实际的根分区设备名;挂载到了 /mnt 目录。

  3. 进入目录

    cd /mnt
    

    此时 ls 命令可以看到 @@home 之类的子卷。

  4. 备份 @ 子卷

    mv @ @_bak1
    

    这条命令移动 @ 并重命名为 @_bak1

  5. 回档

    我们的快照文件通常存放在 @/.snapshots 目录下,@ 变成了 @_bak1,所以现在快照文件在 @_bak1/.snapshots 里面。

    btrfs subvolume snapshot @_bak1/.snapshots/1/snapshot @
    

    这条命令把 @_bak1/.snapshots 目录下序号为 1 的快照变成了新的 @。现在如果重启电脑,就会进入新的 @ 里。

  6. 移动快照文件

    之前创建的快照仍在 @_bak1/.snapshots 里,需要把它移动到新的 @ 里。

    要先删除新的 @ 里的 .snapshots

    rmdir @/.snapshots
    

    然后移动 @_bak1 里的 .snapshots

    mv @_bak1/.snapshots @/.snapshots
    
  7. 删除 @_bak1

    如果想删除备份快照,需要先把里面的子卷删除。

    btrfs subvolume list -o @_bak1
    

    删掉所有 @_bak1 开头的子卷,然后才能删掉 @_bak1

    btrfs subvolume delete -R @_bak1
    

    -R(--recursive) 递归删除子卷里的子卷。

  8. 重启电脑

    reboot
    

关于滚挂和良好的系统使用习惯

  • 滚挂

    Arch Linux 是滚动发行版。滚动是英文直译,原词是 rolling,指一种推送更新的方式,只要有新版本就会推送,由用户管理更新。对应的另一种更新方式是定期更新一个大版本,例如 Fedora 是六个月一更新,由发行方管理更新。滚挂,指的是滚动更新的发行版因为更新导致系统异常。不用担心,只要学习一下正确的更新方式和快照的使用方法就不用担心滚挂问题。

  • 良好的使用习惯

    使用时谨记以下几点:

    1. 别第一时间更新

      如果更新会导致系统异常,社区一定会传出消息,要等一手。

    2. 不要太久不更新

      滚动发行版的软件,尤其是 AUR 上的软件通常会适配最新版本的依赖,隔个一年半载,软件都更了好几个大版本了,你还不更新的话会导致无法使用新安装的软件。

    3. 不要部分更新

      一定要一次性更新所有软件,否则容易出现依赖问题。假设你的系统依赖版本是 15,使用过程中你-Sy更新了软件数据库,新版本软件的系统依赖可能是 16,这时候安装就会报无法处理依赖的错误了。另一个实例是-Sy更新了软件数据库,单独更新了系统依赖版本到16,而系统软件没更新,仍然依赖15,那么软件就无法使用了,严重的情况下会导致整个系统无法使用。这就是为什么-Sy是一个危险的pacman选项组合,安全的使用方法是-Syu,更新软件数据库后更新所有软件。

      不过实际使用时,我偶尔会刻意用-Sy去更新某个软件,只要不更新依赖其实问题不大,-Sy后记得找个时间-Syu就行。

    4. 密钥单独更新

      密钥是唯一可以单独更新的东西。当待更新软件列表出现了 keyring 的时候,先 -Sy 单独更新,然后再 -Syu 更新整个系统。

    5. 做不了解的事情要小心

      系统损坏的原因往往是用户自己的不当操作,明白自己的行为会造成怎样的后果,养成习惯,每次做自己不了解的事情之前都创建快照

拓展内容:downgrade

有时候更新完之后可能反而不好用,这时就要使用 downgrade 退回之前的版本。

降级到太老的版本可能会出现依赖问题;千万不要降级关键依赖。

  • 安装

    yay -S downgrade
    
  • 使用方法:

    sudo downgrade 要回退的软件包
    

    比如如果我要回退 ghostty

    sudo downgrade ghostty
    

万事俱备,接下来选择自己喜欢的桌面环境吧。记住,你随时可以回档到这个时间点,所以感兴趣就试试吧。

下一节:选择桌面环境或窗口管理器