跳转到内容
搜索 AlmaLinux 文档

    浏览当前文档目录

    AlmaLinux 9:XFS 损坏后的修复流程

    在 AlmaLinux 9.8 特权容器(宿主内核 5.14.0-687.54.1.el9_8)中用 512 MB loop 盘实测:mkfs.xfs、挂载写入文件、挂载中执行 xfs_repair、卸载后 xfs_repair -n、破坏 superblock magic、xfs_repair 正式修复、重新挂载读文件。日志:plans/content-expansion/evidence/logs/alma-xfs-repair.log。

    真实业务盘的修复(涉及备份、快照、业务中断窗口)不在本页范围;这里验证的是命令行为与判断顺序。

    Terminal window
    mount /dev/loop0 /mnt/x
    sudo xfs_repair /dev/loop0
    xfs_repair: /dev/loop0 contains a mounted and writable filesystem
    fatal error -- couldn't initialize XFS library

    只要文件系统还挂着(可写),xfs_repair 就直接拒绝。这不是 bug,是保护:修复过程中改元数据,而挂载中的内核还持有旧缓存,修完只会更乱。

    Terminal window
    sudo umount /mnt/x
    sudo xfs_repair -n /dev/loop0
    Phase 7 - verify link counts...
    No modify flag set, skipping filesystem flush and exiting.

    -n 只检查不写盘,输出会列出发现的问题;生产上先干跑、把输出留档,再决定是否真修。

    Terminal window
    sudo dd if=/dev/zero of=/dev/loop0 bs=4 count=1 conv=notrunc
    sudo mount /dev/loop0 /mnt/x
    mount: /mnt/x: wrong fs type, bad option, bad superblock on /dev/loop0, ...

    前 4 个字节是 XFS 的 magic(XFSB)。它被清零后,内核查不到文件系统,mount 报 bad superblock。此时 xfs_repair -n 会提示「需要修改主 superblock,但 -n 模式不能改」。

    第四步:正式修复并从备份恢复

    Section titled “第四步:正式修复并从备份恢复”
    Terminal window
    sudo xfs_repair /dev/loop0
    Phase 7 - verify and correct link counts...
    Note - stripe unit (0) and width (0) were copied from a backup superblock.
    done

    XFS 在磁盘多处保存 superblock 备份,修复时会用备份覆盖损坏的主 superblock。输出里的 Note 就是在告诉你「参数是从备份抄来的」,如果原来有 stripe 参数,需要按提示手工校正。

    Terminal window
    sudo mount /dev/loop0 /mnt/x
    cat /mnt/x/a.txt
    hello

    修复后能挂载、原有文件内容可读,才算这次修复成功。不要只看到 done 就认为没事——必须挂载读一遍关键数据。

    • 挂载中修复:直接拒绝;生产上要先停业务、卸载,或用快照在副本上修;
    • 只跑 -n 就以为修好了:-n 不写盘,什么都不改;
    • 忽略 stripe 提示:从备份恢复的 superblock 可能丢失 stripe 参数,性能会下降。

    练习:在 loop 盘上复现一次修复

    Section titled “练习:在 loop 盘上复现一次修复”
    Terminal window
    sudo dnf install -y xfsprogs
    truncate -s 512M /var/tmp/x.img
    L=$(sudo losetup -f --show /var/tmp/x.img)
    sudo mkfs.xfs -q "$L"
    sudo mkdir -p /mnt/x && sudo mount "$L" /mnt/x
    echo hello | sudo tee /mnt/x/a.txt >/dev/null && sync
    sudo umount /mnt/x
    sudo dd if=/dev/zero of="$L" bs=4 count=1 conv=notrunc
    sudo xfs_repair "$L" | tail -3
    sudo mount "$L" /mnt/x && cat /mnt/x/a.txt

    检查:

    1. mount 在修复前报 bad superblock
    2. xfs_repair 输出含 done
    3. 修复后 cat /mnt/x/a.txt 输出 hello
    4. xfs_repair -n "$L" 输出 No modify flag set(说明已干净)

    常见问题

    为什么挂载状态下 xfs_repair 直接拒绝?

    修复会改元数据,而挂载中的内核仍持有旧的缓存与日志状态,修完会不一致。正确做法是卸载后修,或用快照把卷挂到另一台机器上修。

    xfs_repair -n 和直接 xfs_repair 有什么区别?

    -n 只扫描并报告问题,不写盘;不带 -n 才会真正修改。生产上应先 -n 留档、评估影响,再决定是否执行修复。

    修复提示 stripe unit 被从备份 superblock 复制,要处理吗?

    如果原卷有 RAID stripe 参数,修复后应确认并按提示用 mount -o sunit=,swidth= 校正,否则可能影响性能;无 RAID 的普通盘可忽略。