如何解释 smartctl 消息如 Error: UNC at LBA?
在硬盘上运行 smartctl 时,你通常会获得大量信息,对于没有经验的用户来说可能难以解释。本文试图提供帮助来解释错误消息背后的技术原因。如果你正在寻找是否更换硬盘的建议,我能给你的唯一指导是它可能随时失败,所以最好备份你的数据,但它也可能继续运行很多年。。此外,本文不描述基本的 SMART WHEN_FAILED 检查,而是解释可能即将发生的 HDD 故障的更微妙迹象的解释。
一个特别难以解释的示例是存储最后几个错误的设备错误日志,例如
Error 8910 发生在磁盘上电寿命:7257 小时(302 天 + 9 小时)
当导致错误的命令发生时,设备处于活动或空闲状态。
命令完成后,寄存器为:
ER ST SC SN CL CH DH
-- -- -- -- -- -- --
40 41 1a 00 33 96 61 Error: UNC at LBA = 0x01963300 = 26620672
导致错误的命令之前的命令为:
CR FR SC SN CL CH DH DC Powered_Up_Time Command/Feature_Name
-- -- -- -- -- -- -- -- ---------------- --------------------
60 08 18 00 33 96 40 00 03:09:52.125 READ FPDMA QUEUED
60 88 10 50 06 11 40 00 03:09:52.125 READ FPDMA QUEUED
60 08 08 60 ac 5e 40 00 03:09:52.113 READ FPDMA QUEUED
60 08 00 48 cf 6d 40 00 03:09:52.099 READ FPDMA QUEUED
60 90 f0 b0 ef e5 40 00 03:09:52.065 READ FPDMA QUEUED显然,第一行显示此错误何时发生。然而,其他行不那么明显。让我们检查下一部分:
命令完成后,寄存器为:
ER ST SC SN CL CH DH
-- -- -- -- -- -- --
40 41 1a 00 33 96 61 Error: UNC at LBA = 0x01963300 = 26620672虽然此部分还显示了错误发生时某些寄存器的内容,但其有趣的部分是错误描述 Error: UNC at LBA = 0x01963300 = 26620672.
LBA 是逻辑块地址,即硬盘上的某个逻辑地址。它以十六进制形式 0x01963300 和十进制形式 26620672 显示。要将其转换为字节地址,你需要将其乘以 smartctl 输出头部列出的值:
扇区大小: 512 字节逻辑/物理在几乎所有情况下,此值为 512 字节,因此在此示例中字节偏移量为 26620672 * 512 = 13629784064 = 12.69 GiB。在某些情况下,在 GParted 等工具中查找此地址以查看错误发生在哪个分区可能会有帮助。另请参见此 smartmontools HOWTO详细描述此过程。
UNC 错误
错误消息现在告诉我们在此 LBA 发生了名为 UNC 的错误。UNC 是UNCorrectable的简写,意思是在此 LBA 从硬盘读取的数据已损坏且无法纠正。
硬盘不仅本身存储你的数据,还自动计算所谓的纠错码(ECC)。虽然这些数学代码有许多子类型,但它们有一个共同点:给定一组可能轻微损坏的字节(例如存储在硬盘上的字节)(即某些 0 位现在变为 1 位或反之)和匹配的 ECC 代码(由几个额外字节组成),合适的解码器可以恢复有限数量的位错误。在大多数情况下,ECC 代码也可以检测错误 - 例如,某个特定的 ECC 代码可能能够纠正两字节中的一位翻转,但可以检测到两字节中最多三位翻转。
如果位翻转多于 ECC 可以恢复的(但不多于它可以检测的),这会导致不可恢复的错误 - UNC。如果位翻转多于 ECC 可以检测的,任何事情都可能发生:通常,从 ECC 计算的数据将损坏,或者可能根本检测不到错误。
注意此解释高度简化。例如,ECC 代码不作为与数据分离的字节存储,而是在数据上计算数学函数,产生一组比原始数据集更大的字节 - 包含数据本身加上错误恢复额外数据。换句话说,ECC 数据加上数据本身混合在一起。
这对解释有多个后果。首先,这意味着物理上可以读取数据,但似乎不正确。这意味着
其他错误消息
虽然 UNC 错误相当频繁地发生,但还有其他更罕见的错误,你找不到太多文档。
所有 smartctl 错误消息有一个权威来源:smartmontools 源代码。
我们可以在 ataprint.cpp 中找到错误描述(另请参见源 tarball 中的 GPL 许可信息):
const char *abrt = "ABRT"; // 已中止
const char *amnf = "AMNF"; // 未找到地址标记
const char *ccto = "CCTO"; // 命令完成超时
const char *eom = "EOM"; // 媒体结束
const char *icrc = "ICRC"; // 接口 CRC 错误
const char *idnf = "IDNF"; // 未找到 ID
const char *ili = "ILI"; // 此位的含义是命令集特定的
const char *mc = "MC"; // 媒体已更改
const char *mcr = "MCR"; // 媒体更改请求
const char *nm = "NM"; // 无媒体
const char *obs = "obs"; // 已过时
const char *tk0nf = "TK0NF"; // 未找到磁道 0
const char *unc = "UNC"; // 不可纠正
const char *wp = "WP"; // 写保护
实际上,即使你专业地使用硬盘,你也只会遇到这些错误中的少数几个。其中一些错误如 MC、MCR 或 NM 也与硬盘热插拔相关,不一定代表与硬盘健康本身相关的错误。
一个重要的错误是 ICRC - 接口 CRC 错误。这意味着在硬盘连接的 IDE/SATA 或 PCIe 总线上检测到错误。虽然这很罕见,可能由 HDD 本身引起,但可能意味着你的芯片组(控制例如 SATA 的硬件)已损坏 - 在这种情况下,更换硬盘不会修复问题。可能还存在间歇性的电缆连接。
这些错误有多严重?
在大多数硬盘的寿命期间,特别是消费型号,会发生错误 - 在更可能遇到高加速度力的便携设备中更是如此。
将好的硬盘与寿命末期的硬盘区分开来(不包括那些无警告失败的)通常是新错误的频率。如果你查看 HDD 的总寿命,即 Power_On_Hours 或类似值:
9 Power_On_Hours 0x0032 082 082 000 Old_age Always - 8586并将该值(在此示例中为 8586)与最后一次错误时的寿命比较,
Error 8911 发生在磁盘上电寿命:7257 小时在此示例中为 7257,你可以看到自最后一次错误以来已经过了一千多个 HDD 运行小时。这表明没有可能导致硬盘破坏的机械缺陷,而只是几个有缺陷或损坏的扇区。UNC 错误甚至不一定意味着扇区物理损坏。
通常硬盘错误在访问非常少的文件(例如每隔几年才打开一次的存档视频文件)时触发。当此类文件中由于任何原因有足够的位翻转时,这可能导致大量 HDD 错误同时出现。
另一个指标是硬盘遇到的总错误数,即 8911 在
Error 8911 发生在磁盘上电寿命:7257 小时or in
ATA 错误计数:8911(设备日志仅包含最近的五个错误)虽然不是所有硬盘都显示此数字,但非常高的数字或快速增长的数字表明驱动器存在某些物理问题。仅与少数坏扇区相关的问题会导致错误计数器突然跳变,但之后。但请注意,高错误计数器可能有其他原因,例如与硬盘的连接不良或间歇性。
另请参见此之前的文章了解如何修复坏的 HDD 扇区。