字数 1826,阅读大约需 10 分钟
Btrfs 的多设备管理与 LVM/ZFS 思路不同——没有 zpool / VG 概念,所有设备都属于同一个文件系统。本篇讲清 device add/delete/replace/balance 的用法。
一、Btrfs 多设备 vs LVM/ZFS
| | | |
|---|
| 无(直接是 FS) | | |
| btrfs device | | |
| btrfs device add | vgextend | zpool add |
| btrfs device delete | vgreduce | zpool remove |
| | | |
核心差异:
- • Btrfs 没有"池"概念——mkfs 直接管所有设备
二、查看设备
2.1 设备列表
# 1. 看文件系统总览
$ btrfs filesystem show /mnt
Label: 'mydata' uuid: a1b2c3d4-...
Total devices 2 FS bytes used 1.20GiB
devid 1 size 10.00GiB used 1.50GiB path /dev/sdb
devid 2 size 10.00GiB used 1.50GiB path /dev/sdc
# 2. 看挂载点对应的设备
$ btrfs device stats /mnt
/dev/sdb [/mnt].write_io_errs 0
/dev/sdb [/mnt].read_io_errs 0
/dev/sdb [/mnt].flush_io_errs 0
/dev/sdb [/mnt].corruption_errs 0
/dev/sdb [/mnt].generation_io_errs 0
/dev/sdc [/mnt].write_io_errs 0
...
# 3. 看每个设备的分配
$ btrfs filesystem usage /mnt
Overall:
Device size: 20.00GiB
Device allocated: 3.00GiB
...
2.2 设备使用率
# 看每个设备的 used / total
$ btrfs device usage /mnt
/dev/sdb, ID: 1
Device size: 10.00GiB
Data,RAID1: 1.00GiB
Metadata,RAID1: 1.50GiB
System,RAID1: 8.00MiB
Unallocated: 7.50GiB
/dev/sdc, ID: 2
...
三、加设备
3.1 物理加盘
# 1. 确认盘
$ lsblk /dev/sdc
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdc 8:32 0 10G 0 disk
# 2. 加到 Btrfs
$ btrfs device add /dev/sdc /mnt
# 或
$ btrfs device add /dev/sdc /mnt -f
# -f 强制(如果盘有旧数据)
# 3. 验证
$ btrfs filesystem show /mnt
Total devices 2 FS bytes used 1.20GiB
devid 1 size 10.00GiB used 1.50GiB path /dev/sdb
devid 2 size 10.00GiB used 0.00GiB path /dev/sdc
注意:
- • 数据仍按原 profile 存储(如 raid1 用 sdb+sdc 镜像)
3.2 加盘时指定 profile
# 不支持(device add 不能指定 profile)
# profile 在 mkfs 时定
# 加盘后用 balance 转换
四、删除设备
# 1. 移除设备
$ btrfs device remove /dev/sdc /mnt
# 或
$ btrfs device remove missing /mnt # 移除已失效的盘
# 2. 看进度
$ btrfs balance status /mnt
前提:删除设备时,剩余设备必须有足够空间。
例:
- • 当前:raid1 用 sdb + sdc(每份数据 1 份在 sdb、1 份在 sdc)
- • 但数据在 sdb 是 1 份,不够 → 删除失败
解决:
# 1. 先转 single
$ btrfs balance start -dconvert=single /mnt
# 2. 再删
$ btrfs device remove /dev/sdc /mnt
五、替换设备
5.1 故障盘替换
# 1. 看状态
$ btrfs filesystem show /mnt
# 某盘 missing 或 error
# 2. 移除 missing
$ btrfs device remove missing /mnt
# 3. 物理换盘
# 4. 加新盘
$ btrfs device add /dev/sdc_new /mnt
# 5. balance 重建数据
$ btrfs balance start -dusage=80 /mnt
# ^^^^^^^^^^ 使用率阈值
5.2 在线替换
# 直接替换(先加新盘,移数据到新盘,移完后再删旧盘)
$ btrfs replace start /dev/sdb /dev/sdb_new /mnt
# 看进度
$ btrfs replace status /mnt
# 或
$ btrfs replace status /dev/sdb
注意:btrfs replace 是较新的命令,早期内核可能不支持。回退到 device add/remove + balance 方式。
六、Balance(数据重平衡)
6.1 什么是 balance
btrfs balance 重新分配所有数据到当前设备集,按指定 profile 重新分布。
balance 把数据从:
- 单盘的 1 份 → 重新分布到 raid1 的多份
- raid0 → 重新分布到 raid10
- 不平衡的设备 → 平衡的设备
6.2 命令
# 启动 balance
$ btrfs balance start /mnt
# 启动时指定 profile 转换
$ btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt
# 启动时限制使用率阈值(只平衡用得多的块)
$ btrfs balance start -dusage=80 /mnt
# 看状态
$ btrfs balance status /mnt
# 取消
$ btrfs balance cancel /mnt
# 暂停
$ btrfs balance pause /mnt
6.3 实战:单盘 → RAID1
# 1. 加盘
$ btrfs device add /dev/sdc /mnt
# 2. balance 转 raid1
$ btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt
# 时间取决于数据量
# 3. 验证
$ btrfs filesystem df /mnt
Data, RAID1: total=2.00GiB, used=1.20GiB
Metadata, RAID1: total=1.50GiB, used=128.00KiB
6.4 实战:扩容(加新盘)
# 1. 加 2TB 新盘
$ btrfs device add /dev/sde /mnt
# 2. balance(让数据分布到所有设备)
$ btrfs balance start -dusage=50 /mnt
# ^^^^^^^ 整理使用率 > 50% 的 chunk
# 3. 验证
$ btrfs filesystem usage /mnt
# 看到所有设备都被使用
6.5 balance 性能
balance 性能受限:
建议:
- • 用
btrfs balance pause/resume 控速
七、扩容策略
7.1 容量扩张
# 加新设备
$ btrfs device add /dev/sdX /mnt
# 数据会自动分布到新设备
# 或用 balance 强制重新分布
$ btrfs balance start -dusage=0 /mnt
特点:
- • 不需要指定 RAID 模式(除非做 balance convert)
7.2 缩减
# 1. 移除设备
$ btrfs device remove /dev/sdb /mnt
# 2. balance(迁移数据到其他设备)
$ btrfs balance start -dusage=0 /mnt
前提:剩余设备必须有足够空间。
7.3 替换大硬盘
# 1. 加新盘
$ btrfs device add /dev/sdb_new /mnt
# 2. balance 平衡到新盘
$ btrfs balance start -dusage=0 /mnt
# 3. 移除旧盘
$ btrfs device remove /dev/sdb /mnt
八、scrub 配合 balance
| |
|---|
btrfs scrub | |
btrfs balance | |
btrfs filesystem defragment | |
三者是不同的运维命令:
- • balance:重分布,扩容 / 改 RAID 时跑
九、实战案例
案例 1:单盘 → 2 盘 RAID1
# 1. 准备:单盘 /dev/sdb,文件系统已建
$ btrfs filesystem show /mnt
# 1 个设备,data single
# 2. 加新盘
$ btrfs device add /dev/sdc /mnt
# 3. 转 RAID1
$ btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt
# 4. 监控
$ btrfs balance status /mnt
$ btrfs filesystem df /mnt
案例 2:扩容(4 盘 → 6 盘)
# 当前:4 块 4TB 盘 raid10
# 目标:6 块 4TB 盘 raid10
# 1. 加 2 块新盘
$ btrfs device add /dev/sdf /mnt
$ btrfs device add /dev/sdg /mnt
# 2. balance(重新分布到 6 盘)
$ btrfs balance start -dusage=0 /mnt
案例 3:换盘(故障盘)
# 1. 故障盘识别
$ btrfs device stats /mnt
# 某盘 errors > 0
# 2. 加新盘
$ btrfs device add /dev/sdc_new /mnt
# 3. balance(迁移数据)
$ btrfs balance start -dusage=0 /mnt
# 4. 移除故障盘
$ btrfs device remove /dev/sdc_old /mnt
十、常见问题
1. "no space left on device"(balance 时)
balance 需要临时空间:
# 看可用空间
$ btrfs filesystem df /mnt
# 至少需要 10% 空闲
# 解决:加盘 / 清理数据
2. balance 太慢
# 限制 balance 速度(用后台低优先级)
$ ionice -c 3 btrfs balance start /mnt
# 或用 -dusage 分批
$ btrfs balance start -dusage=80 /mnt
$ btrfs balance start -dusage=50 /mnt
3. device delete 失败
# 看错误
$ btrfs device remove /dev/sdc /mnt
ERROR: error removing device: there is no space
# 解决:balance 转 single 后再删
$ btrfs balance start -dconvert=single /mnt
$ btrfs device remove /dev/sdc /mnt
4. replace 卡住
# 取消
$ btrfs replace cancel /mnt
# 重试
$ btrfs replace start /dev/sdb /dev/sdb_new /mnt
十一、本篇小结
| |
|---|
| btrfs device add /dev/sdX /mnt |
| btrfs device remove /dev/sdX /mnt |
| btrfs replace start /dev/old /dev/new /mnt |
| btrfs balance start /mnt |
| btrfs balance start -dconvert=raid1 /mnt |
| btrfs filesystem show /mnt |
| btrfs device usage /mnt |
关键点:
- • Btrfs 没有 zpool——文件系统直接管设备