上个月家里又多了一台机器:一台淘汰下来的旧台式机,装了 Debian 12,插了两块二手的 4T 机械盘,专门当存储用(下文就叫它 NAS)。二手盘便宜是便宜,但谁也不知道前任主人是怎么用的,心里总有点不踏实。再加上笔记本服务器里那块固态也跑了好几年,我决定把硬盘健康监控认真搞一下。
目标很简单:硬盘出现变坏的苗头时,手机上能收到通知,而不是等到数据读不出来才发现。
smartctl:先看看盘的状况
SMART 是硬盘自己记录的健康数据,Linux 下用 smartmontools 里的 smartctl 来读:
apt install smartmontools
smartctl --scan # 列出能识别的盘
smartctl -i /dev/sda # 型号、序列号、是否支持 SMART
smartctl -H /dev/sda # 总体健康结论,PASSED 不代表万事大吉
smartctl -A /dev/sda # 属性表,重点看这个
smartctl -t short /dev/sda # 发起短自检,一般两分钟左右
smartctl -l selftest /dev/sda # 查看自检记录
smartctl -a /dev/nvme0 # NVMe 盘的输出格式不一样,用 -a 看全部
-H 的结论只有在属性跌破厂商设定的阈值时才会变成 FAILED,往往为时已晚。真正有参考价值的是属性表里的原始值(RAW_VALUE),机械盘我主要看这几项:
- 5 Reallocated_Sector_Ct:已经被重映射的坏扇区数。不为零就要留意,持续增长就该准备换盘了。
- 197 Current_Pending_Sector:等待重映射的可疑扇区。
- 198 Offline_Uncorrectable:离线扫描时发现的无法纠正的扇区。
- 199 UDMA_CRC_Error_Count:传输校验错误,通常是线材或接口的问题,跟盘本身关系不大。
- 9 Power_On_Hours:通电时间,二手盘看这个就知道用了多久。
NVMe 固态是另一套格式,重点看 Percentage Used(寿命消耗百分比)、Available Spare(剩余备用块)和 Media and Data Integrity Errors。
我那两块二手盘,一块通电三万多小时、各项干净;另一块的 199 有几百的计数,换了根 SATA 线之后就不再涨了,算是虚惊一场。
smartd:让它自己定期检查
手动看一次不难,难的是长期坚持。smartd 是 smartmontools 自带的守护进程,可以定时检查属性、安排自检、发现问题时调用脚本通知。配置文件是 /etc/smartd.conf:
# /etc/smartd.conf
# 默认的 DEVICESCAN 一行要注释掉,否则它后面的配置会全部被忽略
#DEVICESCAN -d removable -n standby -m root -M exec /usr/share/smartmontools/smartd-runner
/dev/disk/by-id/ata-DISK_MODEL_SERIAL_A -a -o on -S on -n standby,q -s (S/../.././02|L/../../6/03) -W 4,45,55 -m <nomailer> -M exec /usr/local/bin/smartd-notify.sh
/dev/disk/by-id/ata-DISK_MODEL_SERIAL_B -a -o on -S on -n standby,q -s (S/../.././02|L/../../7/03) -W 4,45,55 -m <nomailer> -M exec /usr/local/bin/smartd-notify.sh
逐个解释一下:
-a:开启一组常用检查,包括健康状态、属性变化、错误日志和自检日志。-o on -S on:打开盘自带的离线数据收集和属性自动保存。-n standby,q:盘处于待机状态时跳过本次检查,不去把它唤醒,q表示跳过时不写日志。-s (S/../.././02|L/../../6/03):每天凌晨 2 点做短自检,周六凌晨 3 点做长自检。格式是“类型/月/日/星期/小时”的正则,星期 1 是周一、7 是周日。两块盘的长自检我错开到了周六和周日,避免同时跑。-W 4,45,55:温度变化超过 4 度记录一次,达到 45 度记一条信息,达到 55 度告警。-m <nomailer> -M exec ...:不发邮件,改为执行指定的脚本。
设备路径用 /dev/disk/by-id/ 下面的名字而不是 /dev/sda,因为 sdX 的顺序每次开机都可能变,by-id 里带着型号和序列号,是固定的。
通知脚本很短。我家里自建了一个 ntfy,直接用 curl 推过去:
#!/bin/sh
# /usr/local/bin/smartd-notify.sh
# smartd 会通过环境变量把出问题的设备和原因传进来
curl -fsS \
-H "Title: SMART alert on $(hostname)" \
-H "Priority: high" \
-d "${SMARTD_DEVICE}: ${SMARTD_FAILTYPE} - ${SMARTD_MESSAGE}" \
https://ntfy.example.com/homelab-disk
记得 chmod +x。改完配置后验证一下:
# 临时在某一行末尾加上 -M test,重启后会立刻触发一次通知,确认收到后再删掉
systemctl restart smartmontools
journalctl -u smartmontools -n 50 # 看 smartd 有没有报配置错误
smartd -q showtests # 打印接下来的自检计划,检查正则写对没有
踩过的坑
- DEVICESCAN 吃掉了后面的配置。 我第一次只是在文件末尾追加了自己的几行,结果怎么都不生效,翻了 man 才知道 DEVICESCAN 之后的行全被忽略了。
- USB 硬盘盒读不到 SMART。 我还有一块放在 USB 硬盘盒里的冷备份盘,直接
smartctl -a报错,要加-d sat告诉它走 SATA 转译。有些廉价硬盘盒的桥接芯片干脆不支持透传,那就没办法了。 - Proxmox 上已经装好了。 PVE 默认就带了 smartmontools,smartd 也在跑,网页的“磁盘”页面能直接看到 SMART 状态。笔记本上我只改了配置文件加上通知,不需要另外安装。
- 服务名。 Debian 12 上的服务单元叫 smartmontools,smartd 只是它的别名,查日志时用 smartmontools 更稳妥。
小结
SMART 不能预测所有故障,很多盘是毫无征兆直接挂掉的,所以它替代不了备份,只是让“慢慢变坏”的那一类问题能被提前发现。配好之后基本不用管,手机上一直收不到消息,就是最好的消息。