当前位置:首页>Linux>Linux Btrfs文件系统之crub、balance、换盘

Linux Btrfs文件系统之crub、balance、换盘

  • 2026-09-18 12:38:37
Linux Btrfs文件系统之crub、balance、换盘

字数 1390,阅读大约需 7 分钟

Btrfs 的日常运维核心:scrub 早发现损坏、balance 重分布、换盘 维护冗余。本篇讲清三件套的命令、频率、最佳实践。

一、scrub:自愈核心

1.1 什么是 scrub

btrfs scrub 遍历所有 extent:

scrub 过程中:
  1. 读出 extent 数据
  2. 计算 CRC32C
  3. 与存储的 csum 对比
  4. 不一致 → 修复(用副本)或标记

scrub 跑完后会自动修复不一致的 extent(前提是有冗余)。

1.2 命令

# 启动 scrub
$ btrfs scrub start /mnt

# 看状态

$ btrfs scrub status /mnt
scrub status for /mnt
        scrub started at Sun Jan 15 03:00:00 2024
        status:         running
        duration:       00:15:30
        data_extents_scanned:    5000000
        tree_extents_scanned:    50000
        data_extents_skipped:    0
        data_bytes_scanned:      20.0GiB
        tree_bytes_scanned:      1.0GiB
        read_errors:             0
        verify_errors:           0
        csum_errors:             0
        super_errors:            0
        malloc_errors:           0
        uncorrectable_errors:    0
        unverified_errors:       0
        corrected_erasures:      0
        ...

# 取消

$ btrfs scrub cancel /mnt

# 恢复(暂停的)

$ btrfs scrub resume /mnt

1.3 scrub 频率

场景
频率
家用
每月
服务器
每周
大容量(>50TB)
每月
冷存储
每季度

原因:scrub 占用 IO,会显著降低 IO 性能(30~50%)。

1.4 自动化 scrub

systemd timer:

# /etc/systemd/system/btrfs-scrub.service
[Unit]
Description=Btrfs scrub

[Service]
Type=oneshot
ExecStart=/sbin/btrfs scrub start /mnt

# /etc/systemd/system/btrfs-scrub.timer

[Unit]
Description=Monthly Btrfs scrub

[Timer]
OnCalendar=monthly
RandomizedDelaySec=4h
Persistent=true

[Install]
WantedBy=timers.target

$ systemctl enable --now btrfs-scrub.timer

cron(传统):

# /etc/cron.d/btrfs-scrub
0 4 1 * * root /sbin/btrfs scrub start /mnt

1.5 scrub 性能

scrub 性能受限于:

  • • 盘数(多盘并行)
  • • 盘速(最慢盘决定)
  • • CPU(csum 计算)

调整:

# ionice:低优先级
$ ionice -c 3 /sbin/btrfs scrub start /mnt

# nice:低 CPU 优先级(影响不大)

$ nice -n 19 /sbin/btrfs scrub start /mnt

二、balance:数据重平衡

2.1 何时跑 balance

触发条件
理由
加新盘后
让数据分布到新盘
RAID 模式变更
转换 profile
设备间数据不均
平衡
长期运行后
整理碎片 chunk

2.2 命令详解

# 基本
$ btrfs balance start /mnt

# 限制使用率

$ btrfs balance start -dusage=80 /mnt
#        ^^^^^^^^^^^ 只平衡使用率 > 80% 的 chunk

#        用法:50 / 80 / 90 ...


# 转 RAID

$ btrfs balance start -dconvert=raid1 /mnt
$ btrfs balance start -dconvert=raid5 /mnt

# 转 metadata

$ btrfs balance start -mconvert=raid1 /mnt

# 暂停

$ btrfs balance pause /mnt

# 恢复

$ btrfs balance resume /mnt

# 取消

$ btrfs balance cancel /mnt

# 状态

$ btrfs balance status /mnt

2.3 balance 性能

balance 写大量新 extent,IO 密集。

# 限制 IO
$ ionice -c 3 btrfs balance start /mnt

# 分批

$ for usage in 80 60 40 20; do
    btrfs balance start -dusage=$usage /mnt
    wait

done

2.4 多久跑一次

触发
频率
加盘后
立即
RAID 模式变更后
立即
定期维护
半年~一年
设备使用不均时
按需

不需要每月跑——这是常见误区。

三、换盘

3.1 故障盘识别

# 1. 看文件系统状态
$ btrfs filesystem show /mnt
# 某盘 missing 或 error


# 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

# 错误数 > 0:盘可能有问题

3.2 故障处理流程

# 1. 确认盘坏了(SMART + dmesg)
$ smartctl -a /dev/sdb
$ dmesg | tail

# 2. 移除 missing 盘

$ btrfs device remove missing /mnt
# 或

$ btrfs device remove /dev/sdb /mnt

# 3. 物理换新盘


# 4. 加新盘

$ btrfs device add /dev/sdb_new /mnt

# 5. balance 重建数据

$ btrfs balance start -dusage=0 /mnt

# 6. scrub 验证

$ btrfs scrub start /mnt

3.3 在线 replace

# 一步搞定(旧盘 → 新盘)
$ btrfs replace start /dev/sdb /dev/sdb_new /mnt

# 看进度

$ btrfs replace status /mnt
# 或

$ btrfs replace status /dev/sdb

# 取消

$ btrfs replace cancel /mnt

注意:

  • • btrfs replace 在较新的内核中才有(≥ 4.18 推荐)
  • • 旧内核用 add + balance + remove 流程

四、scrub + balance + replace 组合实战

场景 1:定期维护

# 每月 1 号 4 点跑 scrub
$ /sbin/btrfs scrub start /mnt

# 看状态

$ btrfs scrub status /mnt
# 跑完会自动结束

场景 2:加盘扩容

# 1. 加盘
$ btrfs device add /dev/sdX /mnt

# 2. balance(让数据分布到新盘)

$ btrfs balance start -dusage=0 /mnt

# 3. 看进度

$ btrfs balance status /mnt

# 4. 完成后跑 scrub 验证

$ btrfs scrub start /mnt

场景 3:换盘

# 1. replace(一步)
$ btrfs replace start /dev/sdb /dev/sdb_new /mnt

# 2. 监控

$ btrfs replace status /mnt

# 3. 跑 scrub

$ btrfs scrub start /mnt

五、监控与告警

5.1 关键指标

指标
健康
警告
data_bytes_scanned
100%
< 80% 终止
read_errors
0
> 0
verify_errors
0
> 0
csum_errors
0
> 0
super_errors
0
> 0
unverified_errors
0
> 0

5.2 智能告警脚本

#!/bin/bash
# /usr/local/bin/btrfs-monitor.sh


MOUNT=$1
STATE=$(btrfs device stats -c $MOUNT 2>/dev/null)

# 1. 看是否有设备错误

for
 dev in $(ls /sys/fs/btrfs/*/devices/ 2>/dev/null); do
    ERRORS=$(cat $dev/error_count 2>/dev/null)
    if
 [ "$ERRORS" -gt 0 ]; then
        echo
 "ALERT: device $(basename $dev) has $ERRORS errors"
        # mail -s "Btrfs Error" root

    fi

done


# 2. 容量检查

USED=$(btrfs filesystem usage -b $MOUNT 2>/dev/null | grep "Used:" | awk '{print $2}' | head -1)
TOTAL=$(btrfs filesystem usage -b $MOUNT 2>/dev/null | grep "Device size" | awk '{print $3}' | head -1)
PCT=$((USED * 100 / TOTAL))
if
 [ "$PCT" -gt 90 ]; then
    echo
 "ALERT: $MOUNT is $PCT% full"
fi

5.3 长期监控工具

  • • btrfsmaintenance(SUSE):自动 balance / scrub / trim
  • • snapper(SUSE):自动快照 + 清理
  • • 自定义 Prometheus exporter(自建)

六、defragment 整理碎片

# 看碎片情况
$ filefrag -v /mnt/data/bigfile | head

# 整理

$ btrfs filesystem defragment /mnt/data/bigfile

# 递归

$ btrfs filesystem defragment -r /mnt/data

# 同时压缩

$ btrfs filesystem defragment -r -czstd /mnt/data

注意:defragment 写时复制,会消耗空间。一般 不需要跑。

七、SSD trim

# 启用 mount 选项
# /etc/fstab

UUID=...  /mnt  btrfs  subvol=@,compress=zstd,discard,defaults  0 0
#                                                ^^^^^^^ 自动 trim


# 或手动

$ fstrim /mnt

八、本篇小结

任务
命令
频率
scrub
btrfs scrub start /mnt
每月
balance
btrfs balance start /mnt
加盘后/按需
replace
btrfs replace start old new /mnt
换盘时
defragment
btrfs filesystem defragment /mnt
罕见

运维口诀:

  • • 每月 scrub(早发现损坏)
  • • 加盘必 balance(数据分布)
  • • 故障盘早换(等真坏了就完了)
  • • 容量监控 ≥ 90%(及时扩容)
  • • SMART 监控(提前预警)

最新文章

随机文章