Btrfs文件系统

Btrfs文件系统简介

Btrfs 通常念成Butter FSBetter FSB-tree FS,是一种新型的写时复制(CoW)Linux 文件系统,Btrfs 在设计实现高级功能的同时,着重于容错、修复以及易于管理。

Btrfs 的一些关键特性和优点:

  1. 快照(Snapshots)

    • 快速创建文件系统的只读或读写副本。
    • 便于备份和恢复操作。
  2. 子卷(Subvolumes)

    • 允许在同一文件系统中创建多个独立的文件系统命名空间。
    • 子卷可以独立地管理快照和配额。
  3. 压缩(Compression)

    • 支持透明压缩(如 zlib、lzo、zstd),减少磁盘空间使用。
  4. 数据完整性(Data Integrity)

    • 通过校验和(checksums)确保数据的一致性和防止损坏。
    • 自动修复数据损坏(如果启用了冗余存储)。
  5. 多设备支持(Multiple Devices)

    • 支持 RAID 配置(RAID0、RAID1、RAID10、RAID5、RAID6),提高数据冗余和性能。
  6. 在线文件系统增长和收缩(Online File System Growth and Shrink)

    • 可以在文件系统挂载时动态调整大小。
  7. 自修复功能(Self-Healing)

    • 检测并修复镜像存储中的数据损坏。
  8. 高效空间管理(Efficient Space Management)

    • 支持精细的空间分配和回收,减少碎片化。

arch 使用 Btrfs 文件系统的特性带来的好处:

  1. 快照 —— archlinux 作为滚动发行版,若滚挂了可以使用 Btrfs 的快照特性快速回滚
    • 若使用传统的 ext4 文件系统,我们可以使用 timeshiftRSYNC 模式进行增量备份。但是,一般来说 RSYNC 方式的快照大小略大于当前实际使用大小,也就是说实际上开启了 timeshiftRSYNC 模式快照相当于磁盘可用空间直接少了一半多。因为虽然 RSYNC 方式的快照是增量的,但历史最久远的快照依然是完整备份,随后才是增量的
  2. 透明压缩 —— 可以大大减少磁盘的使用空间(压缩率大概在 10% 左右)

目录结构

在 Btrfs 中,子卷和快照的目录结构可以自定义,它们不一定以 @ 开头,但很多用户和发行版喜欢使用 @ 作为子卷和快照的命名约定,以便于区分和管理。以下是使用 @ 命名约定的一个示例目录结构:

典型的 Btrfs 目录结构(使用 @ 命名)

/mnt/btrfs
├── @
│   ├── home
│   └── var
├── @home
│   ├── user1
│   └── user2
└── snapshots
    ├── @_snapshot1
    │   ├── home
    │   └── var
    └── @home_snapshot1
        ├── user1
        └── user2

关键点解释

  1. /mnt/btrfs

    • 假设 Btrfs 文件系统挂载在 /mnt/btrfs 目录下。
  2. Subvolumes (子卷)

    • @ 是根子卷,包含系统的根目录(例如 homevar)。
    • @home 是一个单独的子卷,专门用于 /home 目录。
  3. Snapshots (快照)

    • snapshots 目录下包含快照,例如 @_snapshot1@home_snapshot1
    • @_snapshot1 是根子卷 @ 的快照,包含 @ 中的所有目录和文件的副本。
    • @home_snapshot1@home 子卷的快照,包含 @home 中的所有用户目录和文件的副本。

Btrfs 分区管理

格式化为Btrfs文件系统

将整个分区格式化为 Btrfs 文件系统

mkfs.btrfs -L myArch /dev/sdxn

挂载

为了创建子卷,我们需要先将 Btrfs 分区挂载到 /mnt 下:

mount -t btrfs -o compress=zstd /dev/sdxn /mnt/btrfs

创建

将home目录替换到新分区上

要将 home 目录迁移到另一个更大的独立分区并替换现有的 @home 子卷,你可以按照以下步骤进行操作。假设新的分区挂载在 /mnt/new_home

步骤 1:备份数据

确保你已经备份了所有重要数据,以防操作过程中出现问题。

sudo rsync -aHAX --info=progress2 /home/* /path/to/backup/home_backup/

步骤 2:挂载新的分区

首先,将新的分区格式化为 Btrfs 文件系统,并挂载到 /mnt/new_home

sudo mkfs.btrfs /dev/sdXn  # 替换 /dev/sdXn 为实际的新分区设备
sudo mount /dev/sdXn /mnt/new_home

步骤 3:创建新的子卷

在新的分区中创建一个新的 @home 子卷。

sudo btrfs subvolume create /mnt/new_home/@home

步骤 4:同步数据

将现有的 @home 子卷的数据同步到新的子卷。

sudo rsync -aHAXx --info=progress2 /@home/ /mnt/new_home/@home/

步骤 5:更新 fstab

获取分区UUID

sudo blkid /dev/sdXn

编辑 /etc/fstab 文件,添加新的 @home 子卷的挂载信息,并注释掉旧的 @home 挂载信息。

sudo vim /etc/fstab

添加以下内容:
注意一定要确保UUID一致,格式化后值就变了

UUID=12345678-90ab-cdef-1234-567890abcdef  /home  btrfs  subvol=@home,noatime,compress=zstd 0 0

注释掉旧的 @home 挂载行,类似于:

#/mnt/btrfs/@home  /home  btrfs  subvol=@home,noatime,compress=zstd 0 0

步骤 6:卸载旧的 @home 子卷并挂载新的子卷

卸载旧的 @home 子卷并挂载新的 @home 子卷。

sudo umount /home
sudo mount -a  # 按照更新后的 fstab 文件挂载

步骤 7:验证

验证新的 @home 子卷是否正确挂载,并检查数据是否完整。

df -h /home
ls /home

步骤 8:清理旧的 @home 子卷(可选)

由于旧的@home 分区已挂载到 / 目录上,所以会导致看不到 @... 字卷,可通过重新选择一个目录挂载分区,用来删除旧分区上的子卷

sudo mount -o subvol=/ /dev/nvme0n1p6 /mnt/btrfs/

确认新的 @home 子卷已经正常使用后,可以删除旧的 @home 子卷。

sudo btrfs subvolume delete /mnt/btrfs/@home

然后卸载刚才的挂载即可

sudo umount /mnt/btrfs

总结

通过上述步骤,你可以将 home 目录迁移到一个更大的独立分区,并替换现有的 @home 子卷。确保在操作前备份重要数据,并仔细检查每一步的执行情况。