作为一名高级系统运维工程师,Linux 磁盘故障是我们处理频率最高的底层故障之一。磁盘故障通常分为文件系统逻辑故障、物理硬件坏道、资源耗尽和挂载/识别异常四大类。 以下是基于生产环境实战经验的完整故障排查与解决方案。前置运维铁律(务必遵守)
故障处理三原则:
不要随意重启:异常关机或重启可能加剧文件系统损坏。
先卸后修:修复文件系统前,必须将分区umount(根分区除外,需进入救援模式)。
操作前备份元数据:修复前建议使用dd备份超级块和分区表(dd if=/dev/sda of=/backup/mbr.bak bs=512 count=1)。
前置运维铁律(务必遵守)
故障处理三原则:
1. 文件系统只读(Read-Only File System)
现象:touch test 报错 Read-only file system,dmesg 中常伴有 EXT4-fs error 或 Buffer I/O error。
1.1 异常关机/非正常重启导致(日志回放失败)
成因:系统意外断电,日志(Journal)数据损坏或未完整回放,内核为保护数据一致性强制置为只读。
解决方案(在线修复优先):
# 1. 查看只读分区(通常为 / 或 /data)mount | grep ”ro,”# 2. 尝试强制重新挂载为读写(针对非根分区)mount -o remount,rw /dev/sdb1 /mnt/data# 若上述命令报错 ”cannot remount ... read-only”,则必须卸载修复# 3. 针对根分区(/)只读 - 必须重启进入救援/单用户模式systemctl reboot# 在GRUB启动项按 'e' 编辑,在 linux 行末添加 rd.break 或 init=/bin/bash# 重新挂载根为读写:mount -o remount,rw /sysroot# 执行日志恢复:e2fsck -fy /dev/mapper/centos-root
1.2 文件系统日志(Journal)损坏修复
方案:
# 卸载故障分区(若为根分区,需用 Live CD 或救援模式)umount /dev/sda3# 强制检查并修复(-f 强制检测,-y 自动yes)fsck.ext4 -fy /dev/sda3# 若超级块正常但日志异常,可尝试清除日志并重建fsck.ext4 -fy /dev/sda3tune2fs -O ^has_journal /dev/sda3# 关闭日志fsck.ext4 -fy /dev/sda3tune2fs -O has_journal /dev/sda3# 重建日志# 重新挂载验证mount /dev/sda3 /mnt/data
2. 文件系统超级块(Superblock)损坏
现象:mount 报错 Structure needs cleaning 或 can't read superblock。
解决方案(利用备份超级块恢复)
# 1. 查看该分区的超级块备份位置(需知道块大小,通常为 1024/2048/4096)mkfs.ext4 -n /dev/sda3# -n 表示不真正格式化,仅打印备份超级块位置# 输出示例:# Superblock backups stored on blocks: # 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632# 2. 使用最近的备份超级块修复(例如备份块 32768)fsck.ext4 -b 32768 -y /dev/sda3# 3. 修复完成后,重新挂载mount /dev/sda3 /mnt/data
3. 磁盘空间未满但无法写入(Inode 耗尽)
现象:df -h 显示空间尚有剩余,但创建文件报错 No space left on device。
排查与解决
# 1. 查看 Inode 使用率(关键指标)df -i# Filesystem Inodes IUsed IFree IUse% Mounted on# /dev/sdb1 5242880 5242880 0 100% /var/log# 2. 查找包含海量小文件的目录(通常是日志、Mail、Squid缓存、Session文件)find /var/log -type f | wc -lfind /var/spool/postfix/maildrop/ -type f | wc -l# 常见陷阱# 3. 解决方案:清理无效文件或增加 Inode(需卸载,极少数情况支持在线扩容)# 删除大量小文件(若数量极大,使用 rsync 技巧加速删除)rsync -av --delete /empty/ /var/log/nginx/cache/# 或使用 find + 管道删除(慎用,负载高)find /var/log/ -name ”*.log” -mtime +30 -delete# 若 Inode 天生不足,需备份数据后重新格式化并指定 -N 参数mkfs.ext4 -N 8000000 /dev/sdb1# 指定 Inode 数量为 800万
4. 磁盘 I/O 错误 / 坏道(Hardware Error / Bad Block)
现象:dmesg 输出 end_request: I/O error, dev sda, sector 123456,/var/log/messages 大量 scsi 错误,应用卡顿。
4.1 使用 SMART 检测物理健康状态
# 查看磁盘整体健康评估(重点关注 Reallocated_Sector_Ct 和 Current_Pending_Sector)yum install smartmontools -y# 或 dnf installsmartctl -a /dev/sda# 执行快速自检smartctl -t short /dev/sda# 查看自检结果smartctl -l selftest /dev/sda
4.2 处理逻辑/物理坏道
# 1. 尝试读写修复(让磁盘重新映射保留扇区)badblocks -sv /dev/sda > /root/badblocks.txt# 扫描坏道# 2. 修复(尝试强制写坏道,触发 remap)dd if=/dev/zero of=/dev/sda bs=4k seek=123456 count=1 conv=noerror,sync# 3. 若坏道集中在某个分区,使用 fsck 标记坏块,使其不再使用fsck.ext4 -l /root/badblocks.txt -y /dev/sda1# -l 将坏道列表加入系统黑名单
4.3 紧急数据抢救(使用 ddrescue)
# 当磁盘有物理损坏时,切忌使用 dd,必须使用 ddrescue 跳过坏块yum install ddrescue -yddrescue -f -n /dev/sda /dev/sdb /root/rescue.map# 第一次拷贝,跳过坏块ddrescue -f -r 3 /dev/sda /dev/sdb /root/rescue.map# 再次尝试深度复读坏块
5. 磁盘设备识别异常 / UUID 冲突 / 盘符漂移
现象:重启后 /dev/sda 变成了 /dev/sdb,系统无法挂载 /etc/fstab 中的目录,进入紧急模式(Emergency Mode)。
解决方案(强依赖 UUID)
# 1. 紧急救援模式下,查看所有分区的 UUIDblkid# 2. 编辑 /etc/fstab,将 /dev/sdX 路径全部替换为 UUIDvi /etc/fstab# 修改前:/dev/sda1 /boot ext4 defaults 0 0# 修改后:UUID=xxxx-xxxx-xxxx /boot ext4 defaults 0 0# 3. 重新生成 GRUB 引导(若是根分区变更)grub2-mkconfig -o /boot/grub2/grub.cfg# 4. 若因多路径(MPIO)或 iSCSI 导致设备乱序,建议安装并使用 multipath 管理systemctl start multipathdmpathconf --enable
6. 磁盘挂载进程夯住(D 状态进程 / 卡死)
现象:执行 df -h 或 ls 挂载目录时终端卡死无法 Ctrl+C,ps aux 显示进程状态为D (Uninterruptible Sleep)。
解决方案(切忌 Kill -9,D 状态无法被杀)
# 1. 查看当前挂载点的进程占用lsof +D /mnt/datafuser -mv /mnt/data# 2. 强制卸载(延迟卸载,-l 懒卸载,断开文件系统与 VFS 的关联)umount -l /mnt/data# 3. 卸载后,查看哪个进程还握着句柄(这些进程需重启)lsof | grep '(deleted)' | grep /mnt/data# 重启这些持有句柄的服务(如 NFS、数据库、日志服务)# 4. 如果 umount -l 仍无法处理,尝试重新挂载为只读后再卸载mount -o remount,ro /mnt/dataumount /mnt/data
7. LVM 逻辑卷故障(VG 丢失 / PV 损坏)
现象:lvdisplay 无输出,vgchange -ay 报错 No volume groups found 或 Input/output error。
恢复流程
# 1. 扫描所有 PV(物理卷)pvscan# 2. 尝试强制恢复 VG 元数据(从 /etc/lvm/backup/ 或 /etc/lvm/archive/ 还原)vgcfgrestore -f /etc/lvm/backup/vg_centos -n vg_centos /dev/sda2# 3. 若元数据区损坏,尝试使用 vgck(检查并修复卷组一致性)vgck --updatemetadata vg_centos# 4. 激活卷组vgchange -ay# 5. 若 PV 丢失,尝试重新创建 PV 不丢失数据(使用 pvcreate 恢复 UUID)pvcreate --uuid <原有UUID> --restorefile /etc/lvm/backup/vg_centos /dev/sda2
8. 运维终极保底方案:系统救援模式(Rescue Mode)
当 / 分区损坏且无法进入系统时,使用 CentOS Stream 10 / RHEL 安装 ISO 启动:
选择 Troubleshooting -> Rescue a CentOS Stream system。
挂载系统为读写:mount -o remount,rw /mnt/sysimage。
切换根环境:chroot /mnt/sysimage。
执行上述各类 fsck 修复操作。
9. 日常预防性巡检清单(SRE 必备)
最后总结: 大多数磁盘“只读”故障并非物理坏道,而是文件系统脏标志(Dirty Flag)未清除。fsck 是解决 90% 逻辑故障的“银弹”,但务必在 卸载(umount) 状态下执行。对于生产环境核心业务数据库(如 MySQL / PostgreSQL)所在的磁盘,若出现坏道,优先使用 mysqldump 或 pg_dump 逻辑导出恢复,而非在坏盘上执行 fsck -y,以免数据错乱导致无法恢复。