CentOS服务器跑久了,硬盘是最容易出问题的硬件之一。机械盘的老化、SSD的写入寿命耗尽,往往不会立刻让系统宕机,而是先以偶发的I/O错误、卡顿、目录读取失败等形式表现出来。等到磁盘彻底无法访问才处理,通常已经晚了。这篇文章介绍一套在CentOS下检测坏道、评估磁盘健康状态并搭建自动预警的完整方案。

一、用badblocks做传统坏道扫描
badblocks是CentOS自带的经典坏道检测工具,它直接对块设备做读写测试,能找出已经物理损坏的扇区。它支持四种模式:只读(默认)、非破坏性读写、破坏性写测试和无破坏性写测试。生产环境一般用只读模式,风险最低。
只读扫描的命令很简单,指定-v显示进度,-s在屏幕上显示扫描进度条:
badblocks -v /dev/sdb # 带进度的扫描,输出结果保存到文件 badblocks -sv /dev/sdb > /root/badblocks_result.txt
更实用的做法是配合e2fsck的-l参数,把检测到的坏块列表交给文件系统标记,避免数据继续写到坏块上:
# 先检测坏块并生成列表 badblocks -v /dev/sdb1 > /root/bad-blocks.txt # 将坏块列表交给e2fsck处理 e2fsck -l /root/bad-blocks.txt /dev/sdb1
需要注意的是,badblocks全盘扫描非常耗时,一块4TB的机械盘只读扫描可能要几个小时。如果磁盘上已经有正在写入的业务,扫描期间I/O会被严重挤占,建议在业务低峰期执行,或者用ionice降低扫描进程的I/O优先级。另外,非破坏性读写模式(-n)比只读模式更能发现潜在坏道,但耗时翻倍且有一定风险,首次检测一般先跑只读模式即可。
二、smartctl读取硬盘健康指标
badblocks是事后检测,真正能做到提前预警的是S.M.A.R.T.技术。现代硬盘和SSD内部都会持续记录自身健康数据,通过smartctl(属于smartmontools包)可以直接读取这些指标。先安装并确认磁盘是否支持:
yum install -y smartmontools smartctl -i /dev/sda # 如果显示"SMART support is: Disabled",先开启它 smartctl -s on /dev/sda
一条命令就能得到整体健康结论:
smartctl -H /dev/sda # 输出类似: # SMART overall-health self-assessment test result: PASSED
结果为PASSED说明盘自身评估正常,FAILED则说明盘已经判定自己快不行了,必须立即备份数据并换盘。但只看总体结论不够,真正有价值的细节在-A参数输出的属性表里。机械盘重点盯这几个ID:
- 5 Reallocated_Sector_Ct(重映射扇区数):一旦大于0且持续增长,说明盘上已有坏扇区在被替换,是硬盘衰退最直接的信号。
- 197 Current_Pending_Sector(待映射扇区数):等待重映射的扇区,任何非零值都值得警惕。
- 196 Reallocated_Event_Count(重映射事件次数):短期内快速上升说明坏道在扩散。
- 198 Offline_Uncorrectable:离线检测中无法修复的扇区数,非零基本可以考虑换盘了。
查看详细属性的命令:
smartctl -A /dev/sda | egrep "ID|Reallocated|Pending|Uncorrectable|Power_On"
对于SSD,关注点略有不同,主要看Wear Leveling Count(磨损均衡计数)、Percentage Used(已用寿命百分比)和Media_Wearout_Indicator,这些指标直接反映闪存剩余寿命。另外smartctl -t short可以发起一次短自检(约两分钟),-t long则是深度自检(可达数小时),自检结果用smartctl -l selftest查看,适合放进定期巡检流程。
三、搭建自动化预警方案
手动敲命令做巡检在机器多的时候不现实,需要自动化。smartmontools自带一个smartd守护进程,配置文件在/etc/smartmontools/smartd.conf(旧版本路径可能是/etc/smartd.conf)。最简单的配置是监控所有磁盘,发现属性恶化时发邮件:
# 监控所有磁盘,-a监控所有属性,-m指定告警邮箱 DEVICESCAN -H -m admin@bbccb.com -M daily # 针对特定磁盘监控关键属性变化 /dev/sda -a -d ata -m admin@bbccb.com
保存后执行systemctl enable smartd --now启动服务。如果想自己控制逻辑,也可以写脚本配合crontab。下面这个脚本检查所有磁盘的关键S.M.A.R.T.属性,超过阈值就发告警:
#!/bin/bash
# /root/scripts/disk_health_check.sh
ALERT_EMAIL="admin@bbccb.com"
for disk in $(ls /dev/sd[a-z] 2>/dev/null); do
# 读取重映射扇区数和待映射扇区数
reallocated=$(smartctl -A $disk | awk '/Reallocated_Sector_Ct/{print $10}')
pending=$(smartctl -A $disk | awk '/Current_Pending_Sector/{print $10}')
if [ "${reallocated:-0}" -gt 0 ] || [ "${pending:-0}" -gt 0 ]; then
echo "$disk 磁盘健康异常: 重映射=$reallocated 待映射=$pending" | \
mail -s "磁盘故障预警 $disk" $ALERT_EMAIL
fi
done把它加入crontab,每天早上八点执行一次:
# crontab -e 0 8 * * * /bin/bash /root/scripts/disk_health_check.sh >> /root/scripts/check.log 2>&1
有条件的团队可以把这些指标接入Zabbix或Prometheus,通过node_exporter的smartmon采集器或自定义脚本暴露指标,就能画出重映射扇区的增长趋势图。趋势比单点数值更有说服明力:一块盘三个月内重映射数从0涨到50,即使当前还能用,也应该列入更换计划。
四、软RAID环境下的坏盘处理
很多CentOS服务器用mdadm做了软RAID,这种情况下坏盘的处理流程稍有不同。先用cat /proc/mdstat查看阵列状态,如果输出里出现[U_]这样的标记(U表示正常,下划线表示故障),说明已经有成员盘掉线。处理顺序是:先标记故障,再移除,换盘后加入重建:
mdadm /dev/md0 --fail /dev/sdb1 --remove /dev/sdb1 # 换上新盘分区后加入阵列,触发自动重建 mdadm /dev/md0 --add /dev/sdc1 # 观察重建进度 cat /proc/mdstat
mdadm本身也支持邮件告警,编辑/etc/mdadm.conf,添加MAILADDR admin@bbccb.com,然后设置monitor模式的守护进程:
systemctl enable mdmonitor --now
这样阵列出现降级或成员盘故障时,系统会自动发出邮件通知。最后再强调一点:所有检测和预警手段的目的都是争取换盘时间,而不是修复磁盘。一旦S.M.A.R.T.指标明确恶化,正确的做法永远是尽快备份数据、申请备件、安排窗口换盘,把风险控制在数据丢失之前。
CentOS坏道检测磁盘故障预警smartctl修改时间:2026-09-13 23:00:59