SDB:BTRFS

跳转到:导航搜索


本页面涵盖了 btrfs 的重要诊断和修复步骤,它是 openSUSE LeapopenSUSE TumbleweedopenSUSE Kubic 的默认文件系统

默认子卷

默认情况下,openSUSE 使用 Btrfs 和根分区的快照进行设置。快照允许您在应用更新后轻松回滚系统,或备份文件。可以使用 Snapper 轻松管理快照。

在使用快照回滚系统时,必须确保用户主目录、Web 和 FTP 服务器内容或日志文件等数据不会在回滚过程中丢失或被覆盖。这是通过在根文件系统上使用 Btrfs 子卷来实现的。子卷默认情况下从快照中排除。openSUSE 在安装过程中通过 YaST 提出的默认根文件系统设置包含以下子卷。由于以下原因,它们从快照中排除。

   /boot/grub2/i386-pc, /boot/grub2/x86_64-efi, /boot/grub2/powerpc-ieee1275, /boot/grub2/s390x-emu

无法支持回滚引导加载程序配置。上述目录是特定于架构的。前两个目录存在于 AMD64/Intel 64 机器上,后两个目录存在于 IBM POWER 和 IBM z 系统上,分别。

   /home

如果 /home 不位于单独的分区上,则将其排除以避免在回滚时丢失数据。

   /opt

第三方产品通常安装到 /opt。将其排除以避免在回滚时卸载这些应用程序。

   /root

root 用户的家目录也应在回滚期间保留

   /srv

包含 Web 和 FTP 服务器的数据。将其排除以避免在回滚时丢失数据。

   /tmp

所有包含临时文件和缓存的目录都从快照中排除。

   /usr/local

此目录用于手动安装软件。将其排除以避免在回滚时卸载这些安装。

   /var

此目录包含许多变量文件,包括日志、临时缓存、第三方产品在 /var/opt 中,并且是许多虚拟机镜像和数据库的默认位置。因此,创建此子卷以将所有这些变量数据从快照中排除,并禁用写入时复制创建。

旧 /var/* 子卷布局(2018 年 1 月之前)

在较旧的 *SUSE 发行版(SLE 12/Leap 42.x/和 2018 年 1 月之前安装的 Tumbleweed)中,默认的 btrfs 子卷布局将 /var 视为根文件系统的一部分,而是包含以下子卷在 /var 下

   /var/opt

第三方产品通常安装到 /opt。将其排除以避免卸载这些应用程序

   /var/tmp, /var/cache, /var/crash

所有包含临时文件和缓存的目录都从快照中排除。

   /var/lib/libvirt/images

默认情况下,使用 libvirt 管理的虚拟机镜像的位置。排除以确保在回滚期间不会用旧版本替换虚拟机镜像。默认情况下,此子卷使用无复制写入选项创建。

   /var/lib/mailman, /var/spool

包含邮件或邮件队列的目录从快照中排除,以避免在回滚后丢失邮件。

   /var/lib/named

包含 DNS 服务器区域数据。从快照中排除,以确保在回滚后 DNS 服务器可以运行。

   /var/lib/mariadb, /var/lib/mysql, /var/lib/pgqsl

这些目录包含数据库数据。默认情况下,这些子卷使用无复制写入选项创建。

   /var/log

日志文件位置。从快照中排除,以便在损坏系统的回滚后进行日志文件分析。


压缩的 btrfs 文件系统

在 Leap 和 Tumbleweed 中,支持 Btrfs 文件系统的压缩。使用 compress 或 compress-force 选项并选择压缩算法,lzo 或 zlib(默认)。zlib 压缩具有更高的压缩率,而 lzo 更快且占用更少的 CPU 负载。例如

   mount -o compress /dev/sdx /mnt

如果您创建文件、写入文件,并且压缩结果大于或等于未压缩的大小,Btrfs 将永远跳过该文件的未来写入操作的压缩。如果您不喜欢此行为,请使用 compress-force 选项。这对于具有一些初始不可压缩数据的文件很有用。

请注意,压缩仅对新文件有效。在挂载文件系统时使用 compress 或 compress-force 选项写入的文件不会被压缩。此外,具有 nodatacow 属性的文件永远不会对其扩展进行压缩

   chattr +C FILE
   mount -o nodatacow  /dev/sdx /mnt

关于加密,这与任何压缩无关。在将一些数据写入此分区后,打印详细信息

   btrfs filesystem show /mnt
   btrfs filesystem show /mnt
   Label: 'Test-Btrfs'  uuid: 62f0c378-e93e-4aa1-9532-93c6b780749d
           Total devices 1 FS bytes used 3.22MiB
         devid    1 size 2.00GiB used 240.62MiB path /dev/sdb1

如果希望永久生效,请将 compress 或 compress-force 选项添加到 /etc/fstab 配置文件中。例如

   UUID=1a2b3c4d /home btrfs subvol=@/home,compress 0 0

检查可用空间

通常使用 df 命令检查文件系统使用情况。在 Btrfs 文件系统上,df 的输出可能会产生误导,因为除了原始数据分配的空间外,Btrfs 文件系统还会分配和使用空间来存储元数据。

因此,Btrfs 文件系统可能会报告空间不足,即使看起来仍然有大量可用空间。在这种情况下,用于元数据的空间已全部使用。使用以下命令检查 Btrfs 文件系统上已用和可用的空间

btrfs filesystem show

   sudo btrfs filesystem show /
   Label: 'ROOT'  uuid: 52011c5e-5711-42d8-8c50-718a005ec4b3
           Total devices 1 FS bytes used 10.02GiB
           devid    1 size 20.02GiB used 13.78GiB path /dev/sda3

显示文件系统的总大小及其使用情况。如果最后一行中的这两个值匹配,则文件系统上的所有空间都已分配。

btrfs filesystem df

   sudo btrfs filesystem df /
   Data, single: total=13.00GiB, used=9.61GiB
   System, single: total=32.00MiB, used=16.00KiB
   Metadata, single: total=768.00MiB, used=421.36MiB
   GlobalReserve, single: total=144.00MiB, used=0.00B

显示文件系统的已分配(总计)和已用空间的值。如果元数据的总计和已用值几乎相等,则所有元数据空间都已分配。

btrfs filesystem usage

用户 $ sudo btrfs filesystem usage /

Overall:
    Device size:                  20.02GiB
    Device allocated:             13.78GiB
    Device unallocated:            6.24GiB
    Device missing:                  0.00B
    Used:                         10.02GiB
    Free (estimated):              9.63GiB      (min: 9.63GiB)
    Data ratio:                       1.00
    Metadata ratio:                   1.00
    Global reserve:              144.00MiB      (used: 0.00B)

             Data     Metadata  System
Id Path      single   single    single   Unallocated
-- --------- -------- --------- -------- -----------
 1 /dev/sda3 13.00GiB 768.00MiB 32.00MiB     6.24GiB
-- --------- -------- --------- -------- -----------
   Total     13.00GiB 768.00MiB 32.00MiB     6.24GiB
   Used       9.61GiB 421.36MiB 16.00KiB

显示类似于前两个命令组合在一起的数据。

有关更多信息,请参阅 man 8 btrfs-filesystem 和 https://btrfs.wiki.kernel.org/index.php/FAQ


由于 Snapper 导致磁盘空间已满

如果 Snapper 正在为 Btrfs 文件系统运行,则“设备上没有剩余空间”问题通常是由于系统上存储了过多的快照数据造成的。

您可以从 Snapper 中删除一些快照,但是快照不会立即删除,并且可能无法释放您需要的那么多空间。

要从 Snapper 删除文件

  • 打开终端控制台。
  • 在命令行提示符下,输入 btrfs filesystem show,例如
    用户 $ sudo btrfs filesystem show /

    Label: none uuid: 40123456-cb2c-4678-8b3d-d014d1c78c78
    Total devices 1 FS bytes used 20.00GB
    devid 1 size 20.00GB used 20.00GB path /dev/sda3
    
  • 输入
    用户 $ sudo zramctl /dev/zram0 --algorithm zstd --size "$(($(grep -Po 'MemTotal:\s*\K\d+' /proc/meminfo)/2))KiB"
    此命令创建一个 zram 设备,我们将用作我们完整 btrfs 文件系统的临时、内存支持的存储。您可能需要用另一个整数替换 /dev/zram0 中的 0,如果您已经有 /dev/zram0 设备。
  • 输入
    用户 $ sudo btrfs device add /dev/zram0 /
    这将我们的 zram 设备添加到完整的 btrfs 文件系统
  • 列出 Snapper 中的快照。输入
    用户 $ sudo snapper -c root list
  • 从 Snapper 删除一个或多个快照。输入
    用户 $ sudo snapper -c root delete snapshot_number(s)
    确保首先删除最旧的快照。快照越旧,它占用的磁盘空间就越多。
  • 从文件系统中删除 zram 设备
    用户 $ sudo btrfs device remove /dev/zram0 /
  • 从您的系统中删除 zram 设备
    用户 $ sudo zramctl -r /dev/zram0

如何修复损坏/无法挂载的 btrfs 文件系统

以下是任何重大 btrfs 文件系统问题的推荐步骤,尤其是当它无法挂载时。阅读 dmesg 或 syslog 可能会帮助您确定可以跳过哪些步骤来修复特定问题,但初始步骤通常无论如何都很有用,因为 btrfs scrub 是一个非常安全的修复工具。

  • 启动到合适的替代系统,例如救援 shell、openSUSE 的不同安装、liveCD 或 openSUSE 安装 DVD。您正在运行的 openSUSE 版本的安装 DVD 通常是一个不错的选择,因为它肯定会使用相同的内核/btrfs 版本。最新的 Tumbleweed 磁盘可能更好,因为它将包含较新的内核/btrfs
  • 转到合适的控制台并确保您执行以下操作,以 root 身份
  • 尝试将您的分区挂载到 /mnt,只是为了确认它确实已损坏
mount /dev/sda1 /mnt
  • 如果它挂载 - 您确定它已损坏吗?如果是 - 运行
btrfs scrub start /mnt

以 scrub 系统,并

btrfs scrub status /mnt

以监控它

  • 如果它没有挂载,请尝试 scrub 该设备,以防万一有效
btrfs scrub start /dev/sda1

btrfs scrub status /dev/sda1

进行监控。完成后,尝试挂载,如果成功,则已修复。

  • 如果 scrubbing 不是一个选项或无法解决问题

那么尝试 mount -o usebackuproot

mount -o usebackuproot /dev/sda1 /mnt
Icon-warning.png
警告:上述所有步骤都被认为是安全的,不应对磁盘进行任何破坏性更改。如果您无法通过上述步骤解决问题,您可以继续执行以下步骤,但情况已经严重到足以提交错误报告,请!
  • 运行“btrfs check <device>”
btrfs check /dev/sda1

这无济于事,但请将其日志保存在某个地方,它对错误报告很有用。

  • 认真考虑运行“btrfs restore <device> <somewhereto copy data>”
btrfs restore /dev/sda1 /mnt/usbdrive

这不会修复任何问题,但它会扫描文件系统并恢复它能恢复的一切到已挂载的设备上。如果你的 btrfs 问题实际上是由硬件故障而不是 btrfs 故障引起的,这尤其有用。

  • 运行 "btrfs rescue super-recover <设备>"
btrfs rescue super-recover /dev/sda1

然后尝试正常挂载设备。如果成功,停止操作。

  • 运行 "btrfs rescue zero-log <设备>"
btrfs rescue zero-log /dev/sda1

然后尝试正常挂载设备。如果成功,停止操作。

  • 运行 "btrfs rescue chunk-recover <设备>"
btrfs rescue chunk-recover /dev/sda1"

这将会花费很长时间。然后尝试正常挂载设备。如果成功,停止操作。

  • 如果你之前没有运行,现在务必运行 "btrfs restore <设备> <复制数据的目标位置>"
btrfs restore /dev/sda1 /mnt/usbdrive
  • 此时不使用 btrfs restore,而继续尝试修复,意味着你面临极高的数据丢失风险。 建议使用 btrfs restore 尽可能地恢复数据,然后再继续。
Icon-warning.png
警告: 以上工具有很小的几率造成不希望的更改。 此处之后有更高的损坏风险。 除非你准备好承担选择的后果,否则请勿继续。
  • 现在,只有现在,尝试 btrfsck,即 "btrfs check --repair <设备>"
btrfs check --repair /dev/sda1

如何在 openSUSE/btrfs 上手动重新安装 grub

Icon-warning.png
警告: 从 2023 年 12 月开始,Tumbleweed 和 MicroOS 使用 systemd-boot 代替 Grub

重新安装 grub 的一般方法是三个步骤

  1. 挂载根文件系统并绑定挂载虚拟系统文件夹 (/proc, /sys, /dev)
  2. chroot 到上面挂载的根 FS
  3. 发出适当的 grub 命令来重新安装它。

在 openSUSE/Tumbleweed 上,第一步比较棘手,因为根 FS 和一些子文件夹是子卷。

本节的目的是向你展示一个逐步重新安装 grub 的过程,重点是上述第一步,假设标准的 openSUSE 磁盘布局。

启动

首先使用 openSUSE Leap 或 Tumbleweed 安装介质(在 USB 存储设备上)启动计算机。

使用“救援系统”菜单选项获取完整的 root shell。 在 openSUSE 安装介质上,它位于“更多...”菜单下。

识别启动磁盘和分区

完成 USB 启动后,你将获得一个交互式 root shell,以发出将 fdisk 恢复使用的命令。

第一件事是识别你安装了 openSUSE 的磁盘和分区。为此,你可以使用 lsblk -f 来列出当前磁盘驱动器、分区和文件系统类型。 查找 FSTYPE 为 btrfs

lsblk -f
NAME   FSTYPE FSVER ...
sda                 ...
|-sda1 ntfs         ...
|-sda2 ntfs         ...
|-sda3 ntfs         ...
`-sda4 btrfs        ...

基于以上信息,看起来 openSUSE 磁盘和分区是/dev/sda4.

Icon-warning.png
警告: 你的可能不同!!!

上面的示例来自一个磁盘,其中另一个操作系统与 openSUSE/Tumbleweed 双引导安装。

你的 openSUSE/Tumbleweed 安装可能位于不同的分区号,甚至安装在不同的磁盘上。

挂载磁盘

下一步是挂载该分区以访问它。 在挂载之前,我们需要一个文件夹作为挂载点,我们将在/mnt/volume.

mkdir /mnt/volume
mount /dev/sdXn /mnt/volume # use the correct disk and partition you got above.

此时查看/mnt/volume

ls /mnt/volume
.snapshots  bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

如果输出看起来像上面那样,你找到了正确的磁盘/分区来挂载。 如果没有,请立即使用 umount /mnt/volume 卸载 FS 以避免弄乱它,并再次查看 lsblk -f 的输出

  • 检查当前可用的子卷

/mnt/volume挂载 FS 的方式不适合安装 grub。 由于许多系统文件夹实际上是 btrfs 子卷,我们需要以适当的方式挂载这些子卷,为此我们需要知道子卷的名称。

要列出/mnt/volume中的所有子卷名称,请使用以下命令

btrfs subvolume list /mnt/volume
ID 256 gen 31 top level 5 path @
ID 257 gen 6421 top level 256 path @/var
ID 258 gen 6065 top level 256 path @/usr/local
ID 259 gen 6065 top level 256 path @/srv
ID 260 gen 6417 top level 256 path @/root
ID 261 gen 6135 top level 256 path @/opt
ID 262 gen 6421 top level 256 path @/home
ID 263 gen 6016 top level 256 path @/boot/grub2/x86_64-efi
ID 264 gen 6016 top level 256 path @/boot/grub2/i386-pc
ID 265 gen 6327 top level 256 path @/.snapshots
ID 266 gen 6420 top level 265 path @/.snapshots/1/snapshot
... # more lines follows...
Icon-warning.png
警告: 再次说明,上面的结果是针对此磁盘/安装的特定结果。 你的可能不同,特别是 ID 编号。
Take a note of pairs of <ID_number>/path for each relevant path in the following list: 
  • @
  • @/var
  • @/boot/grub2/x86_64-efi
  • @/boot/grub2/i386-pc
  • 创建另一个挂载点到根 FS 并挂载子卷

现在我们将以适当的文件夹挂载上述每个子卷

mkdir /mnt/my-root
mount /dev/sdXn -o subvolid=<ID for path @> /mnt/my-root
mount /dev/sdXn -o subvolid=<ID for path @/var> /mnt/my-root/var
mount /dev/sdXn -o subvolid=<ID for path @/boot/grub2/x86_64-efi> /mnt/my-root/boot/grub2/x86_64-efi
mount /dev/sdXn -o subvolid=<ID for path @/boot/grub2/i386-pc> /mnt/my-root/boot/grub2/i386-pc
  • 绑定挂载

我们需要当前正在运行的系统的虚拟文件夹/proc, /sys/dev

mount /proc -o bind /mnt/my-root/proc
mount /sys -o bind /mnt/my-root/sys
mount /dev -o bind /mnt/my-root/dev

更改 root 并安装 grub

这是最后一步。 这里没有什么新的。 它与你可能在互联网上阅读的其他 FS 类型(如 ext4)没有区别。 运行 chroot/mnt/my-root的全新挂载的 FS,然后运行 update-bootloader --reinit 或/和 grub2-install

chroot /mnt/my-root
update-bootloader --reinit # or grub2-install

参见

相关文章

外部链接