在闲鱼淘服务器硬盘,最怕的不是贵,是卖家那张 smartctl 截图看着一切正常,到手一跑就露馅。Reallocated_Sector_Ct 和 Pending_Sector 都是 0,通电时间也短,看起来跟新盘没区别。但你不知道的是,那块盘可能在你付款前刚被处理过——固件层面做过手脚,或者重映射表被清空过,表面数据漂亮得很。
一开始我也不太信——直到有一回,五块“无任何坏道”的 4T 企业盘摆在面前。上 badblocks 之前,顺手先 dump 了一份 smartctl -a,然后转身去泡咖啡。回来扫一眼,其中一块的 Current_Pending_Sector 已经从 0 跳到了 3。扫描才跑 15%,盘就开始自己招了。那会儿就清楚,光靠卖家一张截图,真靠不住。
smartctl -a /dev/sda | grep -E "Reallocated|Pending"
那行命令我反复跑了几次,发现同一块盘在不同主机、不同镜像下表现会漂。CentOS 7.9 下偶尔掉盘,换 Anolis OS 8 又稳如老狗。这类偶发错误最容易被归结为“线材问题”或者“电源不稳”,但真正原因往往是磁盘内部已经有隐藏扇区在挣扎。
半夜被 Zabbix 叫醒,机房冷得手指发僵,RAID 卡报了一块盘失败。现场重启、拔插、再跑 smartctl,结果全绿——一度以为自己眼花了。后来我不信邪,把盘单独拽到一台旧机上,跑了个非破坏性读扫描,进度条走到一半就蹦出好几处重映射的 LBA。四个多小时熬下来,那块盘确认有物理坏道。如果不是多补了这一趟,单凭 smartctl 那一页「健康」,大概率就当它没事给放过去了。
很多人习惯新盘到手先用 badblocks 扫一遍,没红字就觉得安心。但文件系统层如果已经把坏块重映射走,badblocks 读到的是被接管的好地址,自然看不出异常。磁盘内部早就自我“整容”了,表面数字漂亮得很。要想抓到狐狸尾巴,就得拿多份 smartctl 日志做差异比对,再把 e2fsck -c 拉进来强制让内核记住那些不认祖归宗的扇区。
搞个诊断环境,U盘一插就能扫
手里堆了十几块闲鱼来的盘,一块块插到主力机上跑 badblocks 纯属浪费时间。你需要一个独立的诊断环境,U 盘一插就能进急救模式,不管机器原本装的是什么系统。
Live USB 的选择很多,但多数发行版把 badblocks 和 smartctl 都精简掉了。自己动手做一个,基于 CentOS 7.9 或 Anolis OS 8 的 dracut 急救模式,体积小、启动快,关键是工具一个不落。拿一台能联网的机器,装好 dracut 和 syslinux,然后执行:
dracut --force --add "bash network" /boot/initramfs-diag.img 4.18.0-477.27.1.el8_8.x86_64
grub2-mkconfig -o /boot/grub2/grub.cfg
但这样生成的镜像接近 300MB,里面有太多你根本用不上的驱动和固件。裁剪一下:
dracut --force --omit-drivers "nvme i40e mlx5" --add "bash lvm" --install "badblocks smartctl e2fsck grep cut sort" \
/boot/initramfs-diag-lite.img
把裁剪后的 initramfs 写到 U 盘的 /boot 分区,用 syslinux 引导。启动时在 GRUB 菜单按 e,追加 rd.break 参数就能进入急救 shell——这时候 badblocks 已经可用,smartctl 也能直接调。环境搭好后,剩下的就是怎么批量跑而不盯屏了。
脚本帮你盯着,人可以去喝茶
手动一块块敲命令容易漏盘,或者中途忘记记录日志。写个 shell 循环,挂上时间戳和盘符,跑完自动归档。下面这个脚本放在 /usr/local/bin/batch-scan.sh,插入 U 盘后自动识别所有非系统盘:
#!/bin/bash
LOG_DIR="/mnt/scan_logs/$(date +%Y%m%d_%H%M)"
mkdir -p "$LOG_DIR"
for disk in $(lsblk -dn -o NAME,TYPE | awk '$2=="disk" && $1!="sda" {print "/dev/"$1}'); do
echo "[$(date)] Start scanning $disk" >> "$LOG_DIR/scan.log"
badblocks -sv -b 4096 -c 64 "$disk" > "$LOG_DIR/$(basename $disk)_badblocks.txt" 2>&1 &
done
wait
echo "[$(date)] All scans done" >> "$LOG_DIR/scan.log"
-c 64 每次读 64 个块,内存 2GB 以上的机器不容易触发 OOM。TB 级的盘一个循环下来四五个小时是常事,好在后台跑着,你该干嘛干嘛。坏道扫描跑完后,日志里密密麻麻的 LBA 号看着眼晕——真正有价值的信息其实不在 badblocks 的通过/失败列表里,而在 smartctl 的原始属性变化。
smartctl 日志差异才是利润所在
卖家给你看的那张 smartctl 截图,时间戳可能是一个月前的,甚至是从别的盘复制过来的。你得在扫描前后各抓一次 smartctl -a,对比 Raw_Read_Error_Rate 和 Reallocated_Sector_Ct 有没有跳变。写个小脚本把关键字段抽出来:
#!/bin/bash
DISK=$1
OUTPUT="/mnt/smart_logs/$(basename $DISK)_$(date +%Y%m%d_%H%M).smart"
smartctl -a "$DISK" > "$OUTPUT"
grep -E "Reallocated_Sector_Ct|Current_Pending_Sector|Offline_Uncorrectable|UDMA_CRC_Error" "$OUTPUT"
跑完一轮后,用 diff 对比两次结果——如果 Reallocated_Sector_Ct 从 0 跳到 5,说明扫描过程中磁盘被迫重映射了 5 个扇区,这块盘已经踏上慢性死亡之路。Pending_Sector 非零更危险,那是还没倒腾好的坏道,随时可能在读数据时引发 I/O 错误。一个常见的坑是:不同固件版本的 smartctl 对属性的命名略有差异,有些叫 Reallocated_Sector_Ct,有些叫 Reallocated_Event_Count。建议直接用属性 ID(比如 ID 5 和 ID 197),避免 grep 空手而归:
smartctl -a "$DISK" | awk '/^ 5 / || /^197 / || /^198 / || /^199 /'
这样抓出来的数据格式统一,往后批量分析也方便。
对比日志差异,揪出隐藏坏道
拿到盘别急着跑 badblocks,先在刚上电那一分钟把 smartctl -a 抓全。很多人只看末尾一行通过与否,真正能咬人的牙印藏在 ID5 Reallocated_Sector_Ct 与 ID197 Current_Pending_Sector 的变化里。
卖家截图里 Power_On_Hours 只有两位数?别忘了 Wear_Leveling_Count 也爱露马脚。若前者写着 300,后者却卡在 99%,多半是被工具“洗”过;正常的组合应该是同比例下滑。拿前后两次日志做 diff,一旦出现“归零又回升”的小台阶,基本可以判定被处理过。
有一块 4T 企业盘在 badblocks -w -c64 下全程绿灯,客户差点付款。我把前后 smartctl 导出后发现:Reallocated_Sector_Ct 从 0 跳到 5,Pending_Sector 也长了 2。没过多久它就开始咔咔异响,最终按“与描述不符”成功退款。如果只看单次报告,那这钱就真砸手里了。
#!/bin/bash
# 抽取关键字段,留作后续比对
DISK=$1
LOG="/mnt/logs/$(basename $DISK)_$(date +%Y%m%d).txt"
smartctl -a "$DISK" | awk '/^ 5 / || /^197 / || /^198 / || /^199 /' > "$LOG"
脚本简单,但能把人从十几万行输出里解救出来。记得把两次结果保存到不同文件,然后用 diff -u 看增量——红字一出现,利润空间也跟着亮了。
信息差变现:从检测到议价
前面那套东西跑顺了,剩下就是怎么把技术活儿换成钱。说实话,这步比写脚本简单,但要脸皮厚一点。
一块 4T 企业盘跑一遍 badblocks,按 120W 功耗算,电费大约 1.2 元。U 盘启动盘一次性的,算 0.5 元折旧。你的时间?插盘、敲三条命令、等它跑完,五个盘同时测也就半小时人工。单块成本撑死 5 块钱——这还是算上了万一跑出坏道要重测一次的情况。闲鱼上那些“服务器拆机盘”,标价普遍比全新盘便宜 60%。但你拿到手要是发现 ID5 已经有两位数,那它连这价的四分之一都不值。成本 5 块,潜在损失几百块,这笔账不用算第二遍。
把两次 smartctl 的 diff 截图甩过去,附一句:“Reallocated_Sector_Ct 从 0 跳到 38,按行业标准这盘已经进黄灯区了。要么折价 40%,要么我退回去,运费你出。” 大部分卖家看到带时间戳的日志比对,直接就松口了。我有次压到原价的三分之一,因为那块盘不光 ID197 长了 4,Power_On_Hours 还被清零过——diff 里一行鲜红的 - 300 和 + 0 摆在那,对方连反驳的底气都没有。闲鱼小法庭看证据不看人情,你给出的是可追溯的硬件日志,不是一张截图,这比什么都硬。
筛出来的好盘怎么卖?别裸挂。标题写“已跑 48 小时 badblocks + smartctl 全绿”,描述里放一个精简版日志链接。小型公司、NAS 玩家、甚至学校机房的人,看到这个直接就下单了。他们自己没条件测,或者没耐心等那几十个小时。
# 给买家生成一张“体检单”
cat <<EOF
硬盘型号:$(smartctl -a /dev/sda | grep "Device Model")
通电时间:$(smartctl -a /dev/sda | grep "Power_On_Hours")
测试结果:badblocks -w -c64 完整写验证通过(无坏块)
关键smartctl值:
Reallocated_Sector_Ct: 0
Current_Pending_Sector: 0
Offline_Uncorrectable: 0
测试时间:$(date +%Y-%m-%d)
EOF
加价 25%,买家觉得买了个安心。你赚的不是硬盘差价,是那条 badblocks 命令跑出来的信任。别贪多,一次测两批就行。手里压货超过十块,资金周转就是个坑。
这些操作可能让你亏本
闲鱼淘来的旧盘,第一反应往往是跑个彻底点的测试才放心。但如果你对着一块 SSD 用了 badblocks -w(写入模式全盘扫),这一下可能就废了它的价值。SSD 有控制器在中间做映射,底层物理块早就被磨损均衡打散了;你在逻辑地址上反复写,看到的只是控制器给你的假象,坏道定位完全失真,还白白消耗有限的 P/E。更糟的是,这类写测试会触发内部重分配,把潜在问题扇区从可用池里踢出去,Reallocated_Sector_Ct 等指标被动变化,等你拿报告去谈价,已经没有说服力了。机械盘同理:带数据、带分区的情况下直接写测,很容易把文件系统元数据搞乱,轻则误报,重则丢数据。正确做法是离线——用 Linux 引导修复盘或 Live USB 启动后再扫,必要时只做非破坏性读扫描。
很多人一上来就用默认参数跑,时间成本和错误概率都会把你拖垮。-c 64 这种调优很朴素:每次读取 64 个块合并校验,吞吐更稳,IO 调度更顺,尤其对大容量盘能明显缩短窗口。但不结合内存评估就盲目加大 -c,内核 OOM 杀手可能在后台动手,扫描突然被掐断,日志里只剩半截报错。另一个细节是 smartctl 采样间隔与日志轮转。批量检测时如果 /var/log 所在分区恰好也在目标盘上,写日志会把磁盘置于活跃态,smartmontools 获取属性时更容易碰到不稳定扇区,表现为某些 ID(例如 Reallocated_Sector_Ct、Current_Pending_Sector、Offline_Uncorrectable)跳变。建议在干净的临时目录输出日志,并记录两次 smartctl -a 的完整时间戳,方便后续 diff 对比,而不是只看截图。
- Reallocated_Sector_Ct 非零:已发生重分配,数值越大越不乐观;跳变往往意味着表面问题正在恶化。
- Current_Pending_Sector 非零:待定扇区存在,读写不稳定;若长时间不归零,基本可以判定隐患。
- Offline_Uncorrectable 非零:离线不可纠正错误增加,通常伴随物理损伤,继续使用风险高。
把这些指标串在一起看,远远比盯着一个阈值靠谱——二手服务器盘最坑的地方,根本不是技术多难,而是你能不能躲过那些让人亏到裤衩都不剩的操作。一轮跑下来,筛出几块好盘,跟卖家压价成交,利润就揣进兜里了。不过说真的,不管什么时候,那份完整的原始日志一定要留好,万一哪天翻车了,这才是你唯一的救命稻草。
评论