为什么你的硬盘说挂就挂:SMART 体检的价值
很多 VPS 用户都经历过这样的场景:昨天磁盘 IO 还很正常,今天一觉醒来网站打不开,一查是磁盘故障,数据全没。机械硬盘的坏道是慢慢长大的,固态硬盘的闪存磨损也有迹可循,但默认情况下系统不会主动告诉你。
SMART(Self-Monitoring, Analysis and Reporting Technology,自我监测分析报告技术)就是硬盘内置的"体检系统"。它记录着硬盘每个重要部件的健康数据,比如重映射扇区数、待处理坏扇区数、通电时长、温度等。我们用 smartctl 就能把这些数据读出来,在硬盘真正报废之前提前预警,给备份留出时间。
这篇文章会完整演示:如何安装 smartctl、如何读懂 SMART 属性表、如何跑磁盘自检、如何用 smartd 自动告警、如何排查坏道,以及常见报错的解决办法。
第一步:安装 smartctl
smartctl 来自 smartmontools 软件包,Debian/Ubuntu 和 CentOS/Rocky 的安装命令分别是:
# Debian / Ubuntu
apt update && apt install -y smartmontools
# CentOS / Rocky / AlmaLinux
yum install -y smartmontools
# 验证安装
smartctl --version | head -n 2
安装完成后,先看一下系统里有哪些磁盘设备:
lsblk -d -o NAME,ROTA,SIZE,MODEL
# NAME ROTA SIZE MODEL
# sda 1 2.7T VBOX HARDDISK
# sdb 1 40G VBOX HARDDISK
# nvme0n1 0 512G SAMSUNG MZVL2512HCJQ
ROTA 一列是 1 表示机械硬盘(旋转磁盘),是 0 表示 SSD/NVMe。下面先用机械盘 sda 演示,NVMe 的检查方法在后面的章节单独讲。
读懂 smartctl 输出:先看这三条命令
1. smartctl -i:硬盘基本信息
smartctl -i /dev/sda
输出中重点看这几个字段:
=== START OF INFORMATION SECTION ===
Device Model: WDC WD20EZRZ-00Z5HB0
Firmware Version: 80.00A80
User Capacity: 2,000,398,934,016 bytes [2.00 TB]
SMART support is: Available - device has SMART capability.
SMART support is: Enabled
如果看到 SMART support is: Available 而 Enabled 一栏是 Disabled,用下面命令打开它:
smartctl -s on /dev/sda
2. smartctl -H:一句话健康结论
smartctl -H /dev/sda
SMART overall-health self-assessment test result: PASSED
这是最直接的判断:PASSED 表示各项属性都还没越过阈值,FAILED 表示硬盘已经处于不可靠状态,马上备份数据。
3. smartctl -a:完整属性表(重点)
smartctl -a /dev/sda
输出很长,核心是中间那张属性表。真正需要关心的属性其实就这几个:
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
1 Raw_Read_Error_Rate 0x002f 200 200 051 Pre-fail Always - 0
5 Reallocated_Sector_Ct 0x0033 200 200 140 Pre-fail Always - 0
10 Spin_Retry_Count 0x0032 100 100 097 Old_age Always - 0
194 Temperature_Celsius 0x0022 118 109 000 Old_age Always - 32
197 Current_Pending_Sector 0x0012 200 200 000 Old_age Always - 0
198 Offline_Uncorrectable 0x0010 200 200 000 Old_age Offline - 0
199 UDMA_CRC_Error_Count 0x003e 200 200 000 Old_age Always - 0
解读要点:
- VALUE / WORST:数值越大越好(越接近 200 越健康),降到 THRESH 以下就该报警。
- RAW_VALUE:原始计数值,直接反映问题数量。第 5、197、198 三项的 RAW_VALUE 只要大于 0,就得警惕了。
- 5 Reallocated_Sector_Ct(重映射扇区数):硬盘发现坏扇区后自动用备用扇区替换,这个数字就是已经换过的数量。数值持续增长 = 坏道正在扩散。
- 197 Current_Pending_Sector(待处理扇区):读写异常、等待重映射的扇区数。大于 0 说明磁盘已经在挣扎。
- 198 Offline_Uncorrectable(无法纠正的扇区):已经彻底读不出来的扇区数,大于 0 就是有坏道了。
- 199 UDMA_CRC_Error_Count(接口校验错误):多为数据线/接口接触不良引起,先换线再看。
- 194 Temperature_Celsius:RAW_VALUE 就是摄氏温度,机械盘超过 55°C、SSD 超过 70°C 就要注意散热。
跑一遍磁盘自检:smartctl -t
属性表是硬盘的"体检报告",自检则是主动"做检查"。三种自检类型:
# 短自检:2 分钟左右,检查关键部件
smartctl -t short /dev/sda
# 长自检:1 小时以上(取决于磁盘大小),全盘扫描
smartctl -t long /dev/sda
# 输送自检:专测运输途中损坏,一般不需要
smartctl -t conveyance /dev/sda
自检在后台执行,可以随时查看进度:
smartctl -l selftest /dev/sda
=== START OF READ SELF-TEST LOG ===
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
# 1 Extended offline Completed without error 00% 12876 -
# 2 Extended offline Completed: read failure 10% 12790 43018688
看到 Completed without error 就放心;如果出现 Completed: read failure,后面的 LBA_of_first_error 就是坏道所在的逻辑扇区地址,记下来备用。跑长自检建议选在半夜,避免影响线上业务。
让它自己盯着:smartd 守护进程自动告警
手动查太累,正确姿势是用 smartd 常驻监控,硬盘一出问题立刻告警。编辑配置文件:
vim /etc/smartd.conf
最常用的监控规则(把下面几行加到文件末尾):
# 每 30 分钟检查一次 sda,温度阈值 55°C,属性变化就发邮件
/dev/sda -a -m root@example.com -M test -s (S/../.././02|L/../../7/03) -d sat -n standby,q -W 0,45,55
参数解释:
-a:监控所有 SMART 属性,变化或越阈值即告警。-m 邮箱:告警邮件发到哪里。-M test:启动时先发一封测试邮件,验证告警链路通畅。-s (S/../.././02|L/../../7/03):定时计划,S 表示每天凌晨 2 点跑短自检,L 表示每周日凌晨 3 点跑长自检。-d sat:磁盘走 SATA 接口的固定写法(后面排错章节会讲为什么)。-n standby,q:磁盘休眠时跳过检查,避免把盘唤醒。-W 0,45,55:温度告警,45°C 提醒、55°C 告警。
保存后重载服务:
systemctl restart smartd
systemctl status smartd --no-pager
# 查看启动日志有没有报错
journalctl -u smartd -n 20 --no-pager
邮件发送依赖本机 MTA(如 Postfix)。没有邮件环境的话,可以把 -m 换成脚本:
# 告警时执行 /usr/local/bin/disk_alert.sh
/dev/sda -a -M exec /usr/local/bin/disk_alert.sh
在 /usr/local/bin/disk_alert.sh 里写你自己的推送逻辑,比如发到钉钉/飞书/Server酱:
#!/bin/bash
# 简单的钉钉机器人推送示例
MSG="[磁盘告警] 服务器 $(hostname) 的 /dev/sda 硬盘出现异常,请立即检查!"
curl -s -X POST "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$MSG\"}}"
chmod +x /usr/local/bin/disk_alert.sh
坏道排查:badblocks 与 fsck
如果 SMART 显示有坏扇区,先用 badblocks 做只读检查,确认坏道范围:
# 只读扫描全盘(不破坏数据),4M 块并行 64 个线程,比较快
badblocks -sv -b 4096 -c 65536 /dev/sda
# 只扫描从第 100GB 开始的一段区域
badblocks -sv -b 4096 -c 65536 -o /root/badblocks.txt /dev/sda 209715200 104857600
参数说明:-s 显示进度,-v 显示详细信息,-b 4096 指定块大小,-c 每次测试的块数,-o 文件 把坏块列表写入文件。注意坏块数字的单位是"块"(块大小 4096 字节时,1 块 = 4KB)。
重要提醒:不要对数据盘跑 badblocks -w(写入模式),它会抹掉整盘数据。只有确认是空盘或准备报废的盘才用写入模式。对正在用的数据盘,只读扫描 + SMART 就够判断了。
文件系统层面,可以在只读模式下检查:
# ext4 文件系统只读检查(先卸载或用只读挂载)
e2fsck -f -n /dev/sda1
# 查看检查结果
e2fsck -f -p /dev/sda1 # -p 自动修复,只建议在维护窗口执行
如果坏道集中在文件系统层面报错而 SMART 还没报,可能是逻辑坏道(文件系统损坏),格式化或重写后可能恢复;SMART 里的物理坏道则是不可逆的。
NVMe 固态盘怎么查:nvme-cli
NVMe 盘不走 SMART 这套接口,用 nvme-cli:
# 安装
apt install -y nvme-cli # 或 yum install -y nvme-cli
# 查看设备
nvme list
# 查看健康信息
nvme smart-log /dev/nvme0n1
重点关注这几项:
nvme smart-log /dev/nvme0n1
Smart Health Information Log for NVME device:nvme0n1
critical_warning : 0
temperature : 42 C
available_spare : 100%
percentage_used : 3%
data_units_written : 2,048,130
host_read_commands : 8,231,055,442
media_errors : 0
- critical_warning:非 0 就说明有严重问题(如备用空间不足、温度过高)。
- available_spare:剩余备用块百分比,降到 10% 以下该换盘了。
- percentage_used:寿命消耗百分比,到 100% 说明写寿命耗尽(但通常还能读)。
- media_errors:介质错误计数,大于 0 说明盘在报错。
排错实战:常见报错与解决办法
报错 1:Device is SMART supported: No
三种原因最常见:
# 1. 设备名不对,试试带分区的盘
smartctl -a /dev/sda1
# 2. 老盘或 USB 转接盘不支持 SMART
# 用 lsusb 看是不是 USB 转 SATA 桥接,很多桥接芯片不做 SMART 透传
# 3. 虚拟机里虚拟磁盘。KVM/QEMU 的 virtio 盘可以开虚拟 SMART:
# 宿主机上给虚拟机加参数
# -device virtio-blk-pci,drive=drive0,smart=on
报错 2:Permission denied
# 普通用户执行加 sudo
sudo smartctl -a /dev/sda
# 或把用户加入磁盘组
usermod -aG disk $USER
报错 3:Device open failed, device busy
# 磁盘正在被挂载使用,SMART 查询是只读操作,通常不会冲突;
# 若确实失败,先卸载再查(业务停机窗口内)
umount /dev/sda1 && smartctl -a /dev/sda
报错 4:SATA 盘识别为 "Unknown USB bridge"
外接硬盘盒/USB 转 SATA 的盘,命令要加 -d sat:
smartctl -a -d sat /dev/sdb
报错 5:VPS 上 SMART 数据全是 0 或不变
大多数 VPS 用的是虚拟化存储(网络磁盘、云盘快照底层),宿主根本不给虚拟机透传真实 SMART 数据。这时候 smartctl 查出来没意义,改用云厂商控制台里的"磁盘监控",或者用 iostat -x 1 看 IO 延迟/利用率曲线来判断云盘健康:
iostat -x 1 5
排错模板:SMART 数值波动怎么看
# 看属性随时间的变化,建议每天跑一次并留存
smartctl -a /dev/sda | grep -E "(Reallocated|Current_Pending|Offline_Uncorrectable|Temperature)"
# 连续三天同一属性 RAW_VALUE 单调增长 = 问题在恶化,启动备份并计划换盘
自动化巡检:一行命令看到所有盘的健康状态
把巡检做成 cron 任务,每天跑一次并输出报表:
cat > /usr/local/bin/disk_check.sh <<'EOF'
#!/bin/bash
# 遍历所有物理盘,打印健康状态与关键属性
for dev in $(lsblk -d -o NAME -n | grep -vE 'loop|ram'); do
echo "========== /dev/$dev =========="
smartctl -H /dev/$dev | grep -E "SMART overall|Device"
smartctl -a /dev/$dev | grep -E "(Reallocated_Sector|Current_Pending|Offline_Uncorrectable|UDMA_CRC|Temperature_Celsius)" | awk '{print $2, $NF}'
done
EOF
chmod +x /usr/local/bin/disk_check.sh
# 每天 8 点执行,结果追加到日志
crontab -l 2>/dev/null; echo "0 8 * * * /usr/local/bin/disk_check.sh >> /var/log/disk_check.log 2>&1" | crontab -
# 手动执行一次验证
/usr/local/bin/disk_check.sh
看到 Reallocated_Sector_Ct 或 Current_Pending_Sector 的 RAW_VALUE 开始大于 0 且持续增长,就按这个优先级处理:先异地备份、再降低磁盘负载(迁移数据)、最后在维护窗口换盘。
总结:硬盘健康检查的黄金动作清单
把下面这几件事固化到你的运维习惯里,比任何优化都值钱:
- 装机必查:新盘到手先
smartctl -a看一眼有没有二手货痕迹(通电时长 Power_On_Hours 异常偏高就要找商家)。 - 日常监控:smartd 常驻 + 温度阈值 + 告警脚本,坏盘第一时间知道。
- 定期自检:每周一次长自检,结果对比
smartctl -l selftest日志。 - 关注三项指标:Reallocated_Sector_Ct、Current_Pending_Sector、Offline_Uncorrectable,任一不为 0 就开始备份。
- 永远有备份:SMART 只能预警,不能保命。数据备份 3-2-1 原则(3 份副本、2 种介质、1 份异地)才是最终防线。
硬盘是服务器里唯一一个"会提前告诉你死期"的部件,SMART 就是那个预告机制。学会读懂它,你的 VPS 数据就能多活好几年。




