简要总结
TL;DR: 不能。你无法修复硬盘上的物理坏道。盘片表面一旦划伤,损伤就是永久的。软件只能检测损伤,或请求固件把它隐藏起来。
- 软件能修好吗? 不能。
badblocks、smartctl以及其他任何工具都只能检测或报告坏道。 - 硬盘能自我修复吗? 部分可以。硬盘固件可以把坏道重映射到备用扇区,但这是隐藏损伤,不是治愈损伤。
- 应该怎么做? 如果数据重要,先用
ddrescue克隆磁盘,然后更换硬盘。如果只是测试盘,就观察坏道计数是否增长。
本文用真实命令和真实磁盘数据,说明 badblocks、SMART 和硬盘固件实际做了什么。
什么是坏道?
扇区是硬盘上最小的存储单位。可以把它想象成一本很大的笔记本里的一页。坏道就是硬盘再也无法可靠读取或写入的一页。
扇区变坏后,存储在那里的任何数据都有风险。现代硬盘内置了错误处理机制,但坏道一旦开始出现,通常意味着硬盘正在老化或已经发生物理损伤。
要点: 坏道并不总是立刻可见。操作系统可能直到尝试读取存放在坏位置的文件时才会报错。
坏道的两种类型
并非所有坏道都一样。理解它们的区别是本文最重要的部分。
软(逻辑)坏道
这类坏道是扇区中的数据损坏,但磁盘的物理表面完好。原因包括:
- 硬盘写入数据时断电
- 软件缺陷或恶意软件
- 磁信号减弱或混乱
这类坏道有时可以通过用新数据覆盖该扇区来“修复”。物理磁盘没有损坏,只是上面的信息出错了。
硬(物理)坏道
这类坏道是盘片的实际表面受损。原因包括:
- 读写磁头接触盘片(“磁头碰撞”)
- 密封盘腔内部进入灰尘或污染物
- 多年使用后的正常磨损
- 制造缺陷
没有任何软件能治愈物理损伤。 软件只能请求硬盘使用备用扇区来隐藏损伤。盘片上的划痕会永久存在。
严重警告: 如果你的硬盘存在物理坏道,反复运行高强度测试实际上可能让问题更糟,因为这会继续折磨已经出问题的硬件。
测试盘:来自真实硬盘的数据
本文测试的是一块真实的 250 GB SATA 硬盘。以下是测试前系统看到的信息。
用 lsblk 检查磁盘布局
3.1.1 什么是 lsblk?
lsblk(“list block devices”)显示系统中所有块存储设备:硬盘、SSD、NVMe 盘及其分区。它还会显示哪些分区已挂载、挂载在哪里。这有助于你在运行破坏性命令前确认目标磁盘是否正确。
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 232.9G 0 disk
└─sda1 8:1 0 232.9G 0 part
[...]
注意 sda 是一块 232.9 GB 磁盘,只有一个分区(sda1),并且未挂载。这可以安全测试。
如果它已挂载,应先卸载。这一点非常重要。
用 fdisk -l 显示分区布局和磁盘几何信息
3.2.1 什么是 fdisk -l?
fdisk 是 Linux 上的分区表操作工具。-l 标志表示“列出”,让它显示分区布局和磁盘几何信息,而不做任何修改。它会显示磁盘总容量、扇区数、扇区大小和分区边界。
$ sudo fdisk -l /dev/sda
Disk /dev/sda: 232.89 GiB, 250059350016 bytes, 488397168 sectors
Disk model: 045
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
这确认该磁盘有 488,397,168 个扇区,每个扇区 512 字节。这就是 badblocks 将扫描的总表面范围。
在 Linux 中用 badblocks 检查坏道
什么是 badblocks?
badblocks 是一个 Linux 工具,它通过向每个块写入测试模式、再读回并比较写入与读取的内容,来测试存储设备是否有损坏扇区。它是诊断工具,不是修复工具。它会告诉你哪些块不可靠,但不会修复它们。
badblocks -wsv 实际做什么?
sudo badblocks -wsv /dev/sda
逐项拆解:
警告:破坏性操作:
-w标志会擦除目标磁盘上的所有内容。没有确认提示。它会立即开始写入。只应在没有重要数据的磁盘上使用。
测试模式的含义
badblocks -w 不只是写零。它会依次使用多种测试模式:
0xaa(二进制:10101010)0x55(二进制:01010101)0xff(二进制:11111111)0x00(二进制:00000000)
每种模式都会写入每个块,然后读回并比较。如果读取结果与写入不匹配,该块就会被报告为坏块。
badblocks 不做什么
badblocks 不直接控制或执行扇区重映射。它不修复物理磁盘表面。它只是读取和/或写入扇区,并报告 I/O 错误。不过,当执行写入操作时,硬盘自身的固件可能检测到故障扇区,并将其重映射到备用扇区。这种重映射由硬盘完成,而不是由 badblocks 完成。
手册页本身就警告不要直接使用它
请注意,badblocks 手册页明确建议不要直接运行它。它建议改用 e2fsck -c 或 mke2fs -c,它们会在内部以适合你文件系统的正确块大小调用 badblocks。
为什么手册不鼓励直接使用?
badblocks 产生的块号取决于块大小。默认是 1024 字节。如果你的文件系统使用不同的块大小(例如 4096 字节),而你没有传入 -b,那么输出中的块号并不指向你认为的那些块。通过 e2fsck -c 或 mke2fs -c 运行扫描,意味着块大小在构造上就是正确的。文件系统工具知道自己的块大小;你不一定知道。
数据存在时 -w 的安全替代方案
如果需要测试仍含数据的磁盘,请改用以下方式之一:
-f标志:badblocks通常拒绝在已挂载设备上运行,因为它可能导致系统崩溃或文件系统损坏。-f标志会覆盖这一限制。手册自己的注释很值得记住:“如果你认为自己比badblocks程序更聪明,那你几乎肯定不是。” 请改为卸载设备。
读取 SMART 数据:这些数字意味着什么
即使 badblocks 报告没有错误,SMART 数据也会告诉你硬盘固件自身对其健康状况的了解。
什么是 smartctl?
smartctl 是 smartmontools 软件包的命令行接口。它读取几乎所有现代硬盘和 SSD 内置的 SMART(Self-Monitoring, Analysis, and Reporting Technology,自我监测、分析与报告技术)数据。
SMART 是硬盘内部的健康监测系统,跟踪磨损指标、错误计数、温度和预测性故障迹象。-a 标志让它打印所有可用信息。
在运行任何破坏性测试前,应始终检查硬盘内置的健康报告。
$ sudo smartctl -a /dev/sda
=== START OF INFORMATION SECTION ===
Device Model: GB0250C8045
Serial Number: 9SF0HF1B
Firmware Version: HPG2
User Capacity: 250,059,350,016 bytes [250 GB]
Rotation Rate: 7200 rpm
...
SMART overall-health self-assessment test result: PASSED
...
Self-test execution status: ( 121) The previous self-test completed having
the read element of the test failed.
这里已经出现矛盾:硬盘总体状态显示“PASSED”,但最近一次自检在读取操作中失败。这很常见。SMART 总体状态可能偏乐观,而单项测试会揭示真实问题。
运行你自己的 SMART 自检
sudo smartctl -t short /dev/sdb
sudo smartctl -t long /dev/sdb
sudo smartctl -l selftest /dev/sdb
你可以启动硬盘内置自检,而不进行任何破坏性操作。这些测试在硬盘固件内部运行,并将结果报告给 SMART。
$ sudo smartctl -t short /dev/sda # Usually under 10 minutes
$ sudo smartctl -t long /dev/sda # More thorough, tens of minutes
$ sudo smartctl -l selftest /dev/sda # View results of past tests
短测试检查电气和机械性能,并抽样读取操作。长测试扫描整个表面。两者都在后台运行;之后用 -l selftest 检查结果。
最重要的 SMART 属性
Backblaze 运营着最大的公开硬盘故障数据集之一,它监测 五个 SMART 属性 来预测故障。我们的测试盘报告了其中大部分属性:
45 个重映射扇区到底意味着什么
这块硬盘已经有 45 个扇区被固件永久退役,并用内部备用池中的备用扇区替换。这 45 个扇区是物理损伤。没有软件能恢复它们。现在唯一的问题是是否还会出现更多。
SMART 错误日志详情
错误日志显示同一位置反复出现读取失败:
Error 24 occurred at disk power-on lifetime: 9578 hours
Error: UNC at LBA = 0x0018f66b = 1635947
Commands leading to the error were:
READ DMA EXT
READ DMA EXT
READ DMA EXT
...
Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error
#1 Short offline Completed: read failure 90% 9578 1635947
同一个逻辑块地址(LBA 1635947)出现在每次错误中。这是磁盘表面上一个具体位置,硬盘始终无法读取。短离线自检也在完全相同的位置失败。
SMART 漏掉 23% 的故障
关于 SMART 数据,最重要的注意事项在这里。Backblaze 公布的统计数据 显示,76.7% 的故障硬盘在上述五个关键属性中至少有一个大于零,但这意味着 23.3% 的故障硬盘完全没有显示 SMART 警告。在这些统计中,接近四分之一的硬盘在故障前从未触发这些标志。
SMART 是证据,不是保证:
SMART 检查通过只意味着目前尚未检测到坏情况。它不代表硬盘健康,也不能替代备份。一份干净的报告不等于一张健康证明。要把硬盘与它自己的历史比较,而不是与互联网上的表格比较。
运行 badblocks 测试
现在我们运行破坏性写入测试。由于这块硬盘没有重要数据,这样做是安全的。
$ sudo badblocks -wsv /dev/sda
Checking for bad blocks in read-write mode
From block 0 to 244198583
Testing with pattern 0xaa: 20.31% done, 1:55:02 elapsed, (0/0/0 errors)
# After more time passes, you might see errors appear:
Testing with pattern 0xaa: 45.12% done, 4:20:15 elapsed, (3/1/2 errors)
警告: 如前所述,-w 标志会立即开始向磁盘写入。只有在目标磁盘没有重要数据时才使用它。
如果硬盘已经在物理退化,一次完整的破坏性写入测试可能把它推向极限,使其彻底停止工作。对测试盘来说这可以接受,但值得反复强调。
理解错误计数器:(0/0/0)
进度行末尾括号中的三个数字是测试过程中的错误计数器。
保持耐心并使用电源保护: 完整破坏性测试可能耗时数小时。如果测试期间断电,你可能得到一块被部分擦除的硬盘和不完整的结果。尽可能使用 UPS,并让笔记本电脑保持接通电源。在我们的 250 GB 硬盘上,测试大约花了 9 小时。
测试之后会发生什么?
情况 A:没有发现坏块
如果 badblocks 在所有模式下完成且零错误,你可能会看到:
Pass completed, 0 bad blocks found. (0/0/0 errors)
这意味着磁盘表面通过了写入-读取-校验测试。但请记住,我们的测试盘在 SMART 历史中已经有 45 个重映射扇区。这些在我们开始之前就已经被固件隐藏了。测试只检查是否出现新问题。
情况 B:发现坏块
如果 badblocks 发现坏块,它会打印块号:
1635947
1635948
1635950
Pass completed, 3 bad blocks found. (3/0/3 errors)
注意块 1635947 与 SMART 错误日志中的 LBA 匹配。这是强有力的确认:硬盘固件和 badblocks 指向同一个物理位置。
坏块列表能做什么
你可以把列表保存到文件,并在创建新文件系统时告诉文件系统避开这些块:
7.3.1 什么是 mkfs.ext4?
mkfs.ext4 在分区上创建 ext4 文件系统。这是格式化分区以便 Linux 存储文件的过程。-l 选项(小写 L)让它读取坏块列表,并在文件系统数据结构中将这些块标记为不可用,这样你的文件永远不会写入这些物理位置。
sudo badblocks -wsv -o badblocks_list.txt /dev/sda
sudo mkfs.ext4 -l badblocks_list.txt /dev/sda1
-l 选项告诉 mkfs.ext4 在文件系统中把这些块标记为不可用。你的数据永远不会写入那里。但请记住,这是变通方法,不是修复。
谁真正执行重映射?
这是人们所谓“磁盘修复”中最容易被误解的部分。
关于重映射的真相:
当 badblocks -w 写入坏扇区时,硬盘固件可能决定将其重新分配到备用扇区。但这只在固件于写入操作期间检测到问题时才会发生。badblocks 并不命令重映射。它只是写入数据,由硬盘内部的大脑决定怎么做。
如果你的硬盘仍有数据怎么办?
本文全程假设你的硬盘没有重要数据,这是运行 badblocks -w 的唯一安全条件。如果你的硬盘包含重要文件,不要对它运行破坏性测试。对故障硬盘的每一次读写操作都是风险。
黄金法则:先镜像,后测试
如果数据重要,操作顺序是:
- 使用专为损坏介质设计的工具,将硬盘克隆到健康硬盘或镜像文件
- 验证克隆并从中恢复文件
- 只有在这之后,才对原盘运行测试(如果你仍关心它的状况)
8.1.1 什么是 ddrescue?
ddrescue(GNU ddrescue)是一个数据恢复工具,用于把一个块设备的数据复制到另一个块设备,专为故障硬盘设计。
与 dd 不同,它会智能跳过坏扇区、重试失败区域,并保留一个 mapfile,以便恢复会话中断后继续。它先读取容易的部分,再回头处理损坏区域,从而尽量减少对故障硬盘的压力。
$ sudo ddrescue -f -n /dev/sda /dev/sdb rescue.mapfile
# -f = force (overwrite output)
# -n = skip scraping phase initially (faster first pass)
# rescue.mapfile = progress log you can resume from
# Then retry the bad sectors more aggressively:
$ sudo ddrescue -d -r3 /dev/sda /dev/sdb rescue.mapfile
# -d = direct disc access (bypass kernel cache)
# -r3 = retry bad sectors up to 3 times
停止向故障硬盘写入:
对故障硬盘的每一次写入,都可能覆盖本可恢复的内容,并让已经在挣扎的机械结构承担更多工作。如果数据重要,先克隆,再调查。在存有珍贵数据的硬盘上运行 badblocks -w,就像你还站在桥上时却对一座正在燃烧的桥做压力测试。
结论:你真的能修复坏道吗?
简短回答:不能。你无法修复坏道。
badblocks 不行,smartctl 也不行。任何你能在计算机上运行的软件或工具都不行。扇区一旦物理损坏,就会永久损坏。
软(逻辑)坏道:“可纠正”,不是“已修复”
如果扇区包含损坏数据,但物理表面完好,用新数据覆盖它可以让它重新可读。但你并没有“修复”这个扇区。你只是用新数据覆盖了旧的损坏数据。扇区本身从未物理损坏。
硬(物理)坏道:永久损坏
如果盘片物理表面被划伤、污染或损坏,没有软件能治愈这种损伤。划痕不会因为你运行了一条命令就消失。
硬盘固件做的是从内部备用池中取一个备用扇区替换坏扇区,从而隐藏损伤。损伤仍然存在。你只是再也看不到它了。
软件实际做什么,人们以为它做什么
软件能做的是检测与报告:用 badblocks 扫描块、用 smartctl 读取 SMART 属性与错误日志,以及在写入时由固件触发重映射。它做不到的是恢复盘片上的物理损伤,也无法让已经被固件退役的扇区重新可用。覆盖新数据只能让逻辑损坏的扇区重新可读。
如果硬盘有坏道应该怎么做
扇区一旦因物理损伤变坏,就会永久坏下去。你最多只能:
- 检测它(用
badblocks或 SMART) - 隐藏它(用固件重映射或文件系统坏块列表)
- 更换硬盘(在更多扇区失效之前)
如果数据重要,先用 ddrescue 克隆磁盘,然后更换硬盘。如果磁盘只是用于测试且没有重要数据,你可以继续使用,同时监测坏道计数是否增长。但你并没有“修复”任何东西。你只是管理了症状。
SSD 与 NVMe 的差异
本文的示例是一块转动式硬盘。重映射扇区、待处理扇区这类属性描述的是盘片和读写磁头的老化与损伤,SSD 没有盘片和磁头,这些成因不适用。
smartctl 同样可以读取 SSD 与 NVMe 设备上的 SMART 数据,但属性集合与故障模式与机械硬盘不同。-w 的破坏性写入在任何块设备上都会擦除数据,这一点不因介质类型而改变。
常见误解
- “软件能修复坏道。”
badblocks和smartctl只能检测或报告,物理损伤不会被治愈。 - “SMART 显示 PASSED,硬盘就没问题。” 总体状态可能偏乐观,自检和错误日志可能已经记录了失败;而且 SMART 会漏掉一部分故障。
- “固件重映射等于修复。” 重映射只是用备用扇区把坏扇区藏起来,损伤仍然留在盘片上。
- “坏块列表修好了硬盘。” 那只是让文件系统避开这些块,同样是变通方法。
什么时候应该更换硬盘?
可以继续使用(需谨慎)
重映射扇区为零、待处理扇区为零、ATA 错误为零,并且 badblocks 干净通过。硬盘健康。
密切监测
有少量重映射扇区(例如我们的 45 个),但稳定且不增长。硬盘可能还能用几年,但如果没有备份,不要在上面存放关键数据。
立即更换
重映射扇区快速增长、当前待处理扇区大于零、反复出现 ATA 错误、咔嗒声,或 badblocks 每次测试都发现新的坏道。硬盘正在主动失效。
如何检查计数是否增长
在 badblocks 测试前后运行 smartctl,然后比较:
$ sudo smartctl -a /dev/sda | grep -E "Reallocated|Pending|Uncorrectable"
5 Reallocated_Sector_Ct ... 45
197 Current_Pending_Sector ... 0
198 Offline_Uncorrectable ... 5
如果 Reallocated_Sector_Ct 在 badblocks 之后上升,说明固件在测试期间发现了新的坏道并替换了它们。这证明硬盘仍在退化。
还有一件事:检查线缆
并非所有磁盘错误都意味着硬盘将死。非零的 UDMA_CRC_Error_Count(SMART 属性 199)通常表示 SATA 线缆不良或连接松动,而不是硬盘故障。在丢弃硬盘之前,先尝试更换线缆和端口。我们的测试盘显示 CRC 错误为零,所以问题确实在硬盘上。
资源:




