如何从命令行进行磁盘表面扫描,并修复/重新分配 Linux 中的坏扇区?

klo*_*lor 7 hard-disk fsck

我买了一个带有一些坏扇区的磁盘,计划修复它们,然后将其用作 RAID 6 集群的一部分。我可以在Windows下做坏道修复,有很好的坏道修复工具,但是在Windows下,过程很慢,一个扇区修复需要15分钟。

根据我的经验,Linux 更擅长处理不能及时响应的设备,这导致 Linux 下的处理速度要快得多。但是,我查看了fsck手册,但没有找到任何用于表面和坏块扫描或坏块重新分配的有用选项。

如何从命令行扫描硬盘表面并修复/重新分配 Linux 中的坏扇区?

der*_*ert 9

这个答案是关于磁盘的。SSD 是不同的。此外,这是一个没有数据(或没有您想保留的数据)的磁盘;如果磁盘上有重要数据,请参阅我对“我可以使用单个命令修复硬盘上的坏块吗”的回答

至少在 90 年代后期制作的磁盘自己管理坏块。简而言之,磁盘将通过用备用扇区透明地替换坏块来处理坏块。如果 (a) 在读取时发现该块“弱”,但 ECC 足以恢复数据,它就会这样做;(b) 在写的时候,发现扇区头坏了;(c) 在写入时,如果读取之前检测到该扇区为坏扇区,但数据不可恢复。

磁盘固件通常允许您通过 SMART 属性监控此过程(至少是计数)。通常至少会有一个重新分配的扇区数和两个未决扇区数(读取时发现错误、ECC 失败、尚未写入)。

有两种方法可以让磁盘注意到坏扇区:

  1. 使用smartctl -t offline /dev/sdX告诉磁盘固件做脱机表面扫描。然后,您只需将磁盘放在一边(完全空闲将是最快的),直到它完成(检查 中的“脱机数据收集状态” smartctl -c /dev/sdX)。这通常会更新 SMART 中的“离线不可纠正”计数。(注意:驱动器可以配置为定期自动运行离线检查。)

  2. 让 Linux 读取整个磁盘,例如badblocks -b 4096 -c 1024 -s /dev/sdX. 这通常会更新 SMART 中的“当前挂起扇区”计数。

上述任何一种情况也可能增加重新分配的扇区数——这是情况 (b),ECC 恢复了数据。

现在,要恢复扇区,您只需要写入它们即可。通常,这将是一个简单的pv -pterba /dev/zero > /dev/sdX(或只是普通的cat,或dd),您计划将这些部分作为 RAID 阵列的一部分。RAID init 无论如何都会写入整个磁盘,所以这是毫无意义的。唯一的例外是磁盘的开头和结尾——可能会丢失几十兆字节(由于对齐、标题等)。所以:

disk=/dev/sdX
end=$(echo "$(/sbin/blockdev --getsize64 "$disk")/4096-32768" | bc)
dd if=/dev/zero bs=4096             count=32768 of="$disk"   # first 128 MiB
dd if=/dev/zero bs=4096 seek="$end" count=32768 of="$disk"   # last 128 MiB
Run Code Online (Sandbox Code Playgroud)

我想我设法避免了上面的所有简单的fencepost错误1,因此应该清空磁盘的第一个和最后一个128MiB。然后让 mdadm raid init 写剩下的。不过,如果您愿意,将整个磁盘归零是无害的(除了微不足道的磨损和浪费数小时的时间)。

另一件事要做,如果您的磁盘支持它:(smartctl -l scterc,40,100或任何数字)告诉磁盘您希望它放弃更快地纠正读取错误 - 40 将是 4 秒。这两个数字是读错误和写错误;mdraid 将通过奇偶校验轻松纠正读取错误(并将失败的扇区写回磁盘以使其重新分配)。但是,写入错误会使磁盘无法退出阵列。

PS:请务必留意重新分配的扇区数。该属性将失败是坏消息。如果它不断增加,那也是坏消息。

PPS:确保定期清理您的 RAID 阵列(读取每个扇区并验证所有奇偶校验)。许多发行版已经发布了每月执行此操作的脚本。这将检测并修复任何新的坏块,否则很少读取的坏块可能会持续存在并最终导致重建失败。


1围栏错误——一种由于未能计算一个末端而导致的逐个错误。从命名,如果你有一个栅栏柱每3英尺,有多少栅栏柱在一个9英尺独立式栅栏?正确答案是4;围栏错误是 3,是因为没有计算开头或结尾的帖子。