强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 14 章:故障排查

第 14 章:故障排查

14.1 常见故障分类

故障类型严重程度发生频率
空间不足 (enospc)常见
只读文件系统偶发
设备故障偶发
数据损坏严重罕见
内核 panic严重罕见
挂载失败偶发

14.2 空间不足问题 (enospc)

14.2.1 问题描述

# 症状:系统报告 "No space left on device"
$ touch /data/testfile
touch: cannot touch '/data/testfile': No space left on device

# 但 df 显示有空间!
$ df -h /data
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1       100G   10G   90G  10% /data

14.2.2 原因分析

Btrfs 的 enospc 问题可能由以下原因导致:

原因说明
块组碎片化有空间但无法分配连续的块组
配额限制子卷配额已满
元数据空间不足元数据块组已满
快照占用快照保留了旧数据块
balance 挂起之前的 balance 未完成

14.2.3 诊断步骤

# 1. 查看详细空间使用
sudo btrfs filesystem usage /data

# 重点关注:
# Device unallocated:  0.00B   ← 如果为 0,说明块组全部已分配
# Data ratio:          1.00
# Metadata ratio:      2.00

# 2. 查看块组分配
sudo btrfs filesystem df /data
# Data,single: total=98.00GiB, used=10.00GiB   ← 数据块组分配了很多
# Metadata,DUP: total=2.01GiB, used=200.00MiB  ← 元数据可能不够
# System,DUP: total=8.00MiB, used=16.00KiB

# 3. 检查配额
sudo btrfs qgroup show /data 2>/dev/null | grep -v "none"

# 4. 检查设备统计
sudo btrfs device stats /data

# 5. 检查是否有 balance 在运行
sudo btrfs balance status /data

14.2.4 解决方案

方案 1:Balance 回收空间

# 先取消可能挂起的 balance
sudo btrfs balance cancel /data 2>/dev/null || true

# 渐进式 balance
sudo btrfs balance start -dusage=5 /data
sudo btrfs balance start -dusage=10 /data
sudo btrfs balance start -dusage=20 /data

# 元数据 balance
sudo btrfs balance start -musage=5 /data
sudo btrfs balance start -musage=10 /data

方案 2:清理快照

# 列出所有快照
sudo btrfs subvolume list -s /data

# 删除旧快照
sudo btrfs subvolume delete /data/@snapshots/old-*

# 或使用 snapper 清理
sudo snapper cleanup timeline
sudo snapper cleanup number

方案 3:禁用配额

# 如果配额导致问题
sudo btrfs quota disable /data

方案 4:添加设备扩展

# 添加新设备
sudo btrfs device add /dev/sdc /data

# 立即 balance
sudo btrfs balance start /data

方案 5:紧急空间释放

# 删除不需要的文件
sudo find /data -type f -name "*.tmp" -delete
sudo find /data -type f -size +100M -mtime +30 -delete

# 清空已删除但仍被进程占用的文件
sudo lsof +L1 /data

14.3 只读文件系统

14.3.1 问题描述

# 文件系统变为只读
$ touch /data/testfile
touch: cannot touch '/data/testfile': Read-only file system

# 查看挂载状态
$ mount | grep /data
/dev/sdb1 on /data type btrfs (ro,relatime)

14.3.2 原因

原因说明
设备 I/O 错误磁盘故障或连接问题
内核检测到损坏数据或元数据校验和错误
空间完全耗尽enospc 后转为只读
手动只读挂载mount -o ro

14.3.3 诊断

# 1. 检查内核日志
dmesg | tail -50 | grep -i btrfs
# 常见错误信息:
# BTRFS error (device sdb): bdev /dev/sdb errs: wr 5, rd 0, flush 1, corrupt 0
# BTRFS: error (device sdb) in btrfs_commit_transaction:...

# 2. 检查设备统计
sudo btrfs device stats /data

# 3. 检查空间
sudo btrfs filesystem usage /data

14.3.4 恢复方法

方法 1:重新挂载为读写

# 如果只是临时问题
sudo mount -o remount,rw /data

方法 2:修复设备错误后重新挂载

# 修复设备错误(可能需要更换磁盘)
# ...

# 重新挂载
sudo umount /data
sudo mount /dev/sdb1 /data

方法 3:使用 rescue 选项挂载

# 使用备份的根节点挂载
sudo mount -o rescue=usebackuproot /dev/sdb1 /data

# 使用所有救援选项
sudo mount -o rescue=usebackuproot,nologreplay,skipbalance /dev/sdb1 /data

方法 4:降级模式挂载(RAID)

# RAID 1 模式下,如果一个设备故障
sudo mount -o degraded /dev/sdb1 /data

# 然后替换故障设备
sudo btrfs replace start /dev/sdc /dev/sdd /data

14.4 设备故障处理

14.4.1 检测设备故障

# 检查设备错误统计
sudo btrfs device stats /data
# [/dev/sdb].write_io_errs    0
# [/dev/sdb].read_io_errs     0
# [/dev/sdb].flush_io_errs    5    ← 非零值表示问题
# [/dev/sdb].corruption_errs  0
# [/dev/sdb].generation_errs  0

# 检查 SMART 状态
sudo smartctl -a /dev/sdb

# 内核日志中的设备错误
dmesg | grep -i "error\|fail\|btrfs"

14.4.2 单设备模式处理

# 单设备(无 RAID)故障时:
# 1. 立即备份可读数据
sudo mount -o degraded,ro /dev/sdb1 /mnt/rescue
sudo rsync -av /mnt/rescue/ /backup/

# 2. 尝试修复
sudo umount /mnt/rescue
sudo btrfs check --repair /dev/sdb1  # ⚠️ 危险

# 3. 尝试恢复
sudo btrfs restore /dev/sdb1 /recovery/

14.4.3 RAID 模式处理

# RAID 1 设备故障处理:
# 1. 文件系统自动进入降级模式
sudo btrfs filesystem show /data
# devid    1  size 100.00GiB  used 12.00GiB  path /dev/sdb
# devid    2  size 0.00B     used 0.00B     path /dev/sdc  ← 故障设备

# 2. 替换故障设备
sudo btrfs replace start /dev/sdc /dev/sdd /data

# 3. 等待替换完成
sudo btrfs replace status /data

# 4. 验证
sudo btrfs device stats /data
sudo btrfs scrub start /data

14.5 数据恢复

14.5.1 btrfs restore

# 从损坏的文件系统恢复数据
# btrfs restore 只读取数据,不修改原文件系统

# 恢复所有数据
sudo btrfs restore /dev/sdb1 /recovery/

# 恢复特定子卷
sudo btrfs restore -r 256 /dev/sdb1 /recovery/

# 忽略错误继续恢复
sudo btrfs restore -i /dev/sdb1 /recovery/

# 恢复符号链接
sudo btrfs restore -S /dev/sdb1 /recovery/

# 恢复快照
sudo btrfs restore -s /dev/sdb1 /recovery/

# 指定根节点偏移(高级用法)
sudo btrfs restore -t <bytenr> /dev/sdb1 /recovery/

14.5.2 btrfs check –repair

# ⚠️ 警告:--repair 可能导致数据丢失!
# 只在其他方法都失败时才使用

# 1. 先只读检查
sudo btrfs check /dev/sdb1

# 2. 如果 check 报错,尝试修复
sudo btrfs check --repair /dev/sdb1

# 3. 特定修复选项
sudo btrfs check --init-extent-tree /dev/sdb1  # 修复 extent 树
sudo btrfs check --clear-space-cache v1 /dev/sdb1  # 清除 v1 空间缓存
sudo btrfs check --clear-space-cache v2 /dev/sdb1  # 清除 v2 空间缓存

14.5.3 数据恢复流程

发现故障
    │
    ▼
┌───────────────┐
│ 1. 停止写入   │ (卸载或 remount ro)
└───────┬───────┘
        │
        ▼
┌───────────────┐
│ 2. 备份镜像   │ (dd if=/dev/sdb of=/backup/sdb.img)
└───────┬───────┘
        │
        ▼
┌───────────────┐
│ 3. btrfs check│ (只读检查)
└───────┬───────┘
        │
        ├─ 无错误 → 重新挂载使用
        │
        ▼
┌───────────────┐
│ 4. btrfs      │ (尝试恢复)
│    restore    │
└───────┬───────┘
        │
        ├─ 成功 → 从恢复的数据重建
        │
        ▼
┌───────────────┐
│ 5. check      │ (最后手段)
│    --repair   │
└───────┬───────┘
        │
        ▼
    从备份重建

14.6 内核 Panic 与 Btrfs

14.6.1 常见 Panic 原因

原因说明
内核 bugBtrfs 代码中的 bug
硬件故障内存或磁盘控制器故障
空间耗尽严重 enospc 导致内核 panic
驱动不兼容存储驱动或文件系统模块问题

14.6.2 恢复步骤

# 1. 从 Live CD/USB 启动

# 2. 检查文件系统
sudo btrfs check /dev/sdb1

# 3. 尝试使用备份根节点挂载
sudo mount -o rescue=usebackuproot /dev/sdb1 /mnt

# 4. 如果仍然失败
sudo btrfs restore /dev/sdb1 /recovery/

# 5. 收集日志用于 bug 报告
# /var/log/kern.log 或 journalctl

14.7 故障排查工具

14.7.1 诊断命令速查

命令用途
btrfs filesystem show文件系统概览
btrfs filesystem df空间使用详情
btrfs filesystem usage空间使用分析
btrfs device stats设备错误统计
btrfs scrub status校验状态
btrfs balance status平衡状态
btrfs subvolume list子卷列表
btrfs check文件系统检查
btrfs restore数据恢复
dmesg内核日志
smartctl磁盘 SMART 状态

14.7.2 日志分析

# Btrfs 相关内核日志
dmesg | grep -i btrfs

# 常见日志模式:

# 1. 校验和错误
# BTRFS warning (device sdb): csum error ino 257 off 0 csum 0x1234 expected 0x5678

# 2. 设备 I/O 错误
# BTRFS error (device sdb): bdev /dev/sdb errs: wr 5, rd 0, flush 1

# 3. 空间不足
# BTRFS warning (device sdb): block rsv returned -28

# 4. 只读转换
# BTRFS error (device sdb): commit aborted: -5

14.8 本章小结

故障解决方案
enospc (空间不足)balance 回收 / 清理快照 / 添加设备
只读文件系统检查设备错误 / rescue 挂载 / 替换设备
设备故障 (RAID)btrfs replace 替换
设备故障 (单设备)btrfs restore 恢复数据
数据损坏scrub 发现 / RAID 自动修复
挂载失败rescue=usebackuproot / btrfs check

排查流程

  1. 查看 dmesg 日志
  2. 检查 btrfs device stats
  3. 检查 btrfs filesystem usage
  4. 根据错误类型选择修复方案

扩展阅读