记录一下那天晚上的排查过程。阿里云 2 核 4G 的 CentOS 7.9 机器,/data 是 ext4,上午十点开始 web 目录写不进去,dmesg 里反复出现 JBD2: Detected IO errors while flushing file data,mount 一看 /data 已经是 ro,手动 remount 成 rw 撑不到一分钟又回到只读。
刚开始盯着「磁盘阵列的缓存电池失效,掉电后日志区写了一半」,折腾了半个多小时,排掉了。
真正麻烦的地方在于,几个原因的现象几乎一样。底层云盘出现了不可恢复的写错误,日志区提交失败只能把分区锁成只读。还有一种是jbd2 的日志块落在坏道上,每次恢复日志都读失败。
少数情况下是文件系统本身有元数据冲突,日志重放无法完成。
动手时先把内核里这条链路的报错按时间捞全
dmesg -T | grep -iE 'JBD2|EXT4-fs|I/O error' | tail -40
随后确认是单块盘还是整个挂载点的写错误
smartctl -a /dev/vdb | grep -iE 'Reallocated|Pending|Error'
接着把能读的数据先同步到另一块盘
rsync -aHAX --numeric-ids /data/ /mnt/bak/data/
卸载后做一次完整检查再挂回
umount /data && fsck -f -y /dev/vdb1
别只看报错消失,验证要多做一步。fsck 结束后重新挂载为 rw,连续写入十分钟不再回到只读,dmesg 里没有新的 JBD2 abort。
补一句。日志区坏了 fsck 可能把最近几分钟的写入回滚掉,业务上要能接受这段数据缺口,或者从备份补齐。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
