之前我的 PVE 出现硬盘故障的时候,整个母机都阻塞住了,本来用于高可用的 ZFS mirror, 并没有启动预期中的作用。这里的原因是什么呢?我们来看一段日志:
[ 3.867520] ZFS: Loaded module v2.1.11-pve1, ZFS pool version 5000, ZFS filesystem version 5
[ 35.998221] ata2.00: exception Emask 0x0 SAct 0x700 SErr 0x0 action 0x6 frozen
[ 36.011820] ata2.00: failed command: WRITE FPDMA QUEUED
[ 36.018667] ata2.00: cmd 61/10:40:10:0a:20/00:00:00:00:00/40 tag 8 ncq dma 8192 out
res 40/00:01:00:00:00/00:00:00:00:00/00 Emask 0x4 (timeout)
看起来这个写操作花了超过 30 秒才返回失败。可以想象,如果某个进程在运行过程中也需要访问故障硬盘上的数据,就需要等待很久直到超时返回。由于 linux 中硬盘 I/O 是阻塞的,即使有 ZFS mirror, 也要等到故障的硬盘返回失败,才能去尝试读写下一个硬盘。 Linux 也没有可以中断一个已经启动的硬盘 I/O 操作的机制,软件是没办法控制超时时间的,具体会阻塞多久,完全取决于硬盘在什么时候返回错误。
硬盘的存储和读取机制
至于硬盘在出现故障时为什么要阻塞很久,而不是立刻返回错误,这要从硬盘存储和读取数据的方式说起。
现代硬盘的数据密度非常大,读取时,磁头上产生的信号十分微弱,读取过程其实是一个复杂的信号检测问题。在硬盘变旧,或者受到了什么外来损伤时,磁盘上的数据不一定会立刻消失,而可能是信号变弱。为此,硬盘有前向纠错 (FEC) 机制1,在信号检测中产生少量误码时,可以解码出正确的数据。在信号弱到能否解码的临界点时,随机噪音就会成为决定解码是否成功的因素。因此,硬盘会在解码失败时反复尝试读取,试图解码出正确的数据。
与 RAID 的冲突和解决方案
FEC 和重试是很好的机制。在桌面平台使用的时候,有时旧硬盘出现故障的最初现象,就是读写变慢。但这个机制和 RAID 的设计却是冲突的。 RAID 是一种高可用机制,我们希望在硬盘出故障的时候系统还能继续运行,我们的应用服务不会中断。为此,我们需要出现故障的时候,尽快返回错误,让 RAID 控制器或者操作系统 (soft RAID 场景下) 切换到没有故障的硬盘上继续工作。
为此,硬盘提供了 Error Recovery Control 功能,让 RAID 控制器或者操作系统,可以指定读写操作的超时时间,避免硬盘长时间阻塞在重试过程中。一般硬件 RAID 卡会自动使用这个功能,但如果用的是各种 soft RAID 方案,比如 mdraid, btrfs, ZFS 等,就需要通过软件来启用这个功能。
配置 Error Recovery Control
Error Recovery Contorl 功能通过 SMART Command Transport (SCT) 命令控制。我们可以用 smartctl 或者 smartd 来控制这个功能。
首先需要确认硬盘是否支持这个功能, smartctl -c /dev/sda
可以列出设备支持的 SMART 能力。如果有显示 “SCT Error Recovery Control supported.”, 那就是支持这个功能。
在支持这个功能的情况下,执行
-
smartctl -l scterc /dev/sda
可以显示当前的配置。 -
smartctl -l scterc,<READTIME>,<WRITETIME> /dev/sda
可以设置设置读写超时时间,单位为分秒。如scterc,70,70
会把超时时间设置为 7 秒。7 秒也是 RAID 场景下推荐的超时设置。注意:大部分硬盘支持的最小设置是 6.5 秒。
-
smartctl -l scterc,<READTIME>,<WRITETIME>,p /dev/sda
可以把超时时间持久化保存到硬盘上,以后每次通电时都会应用这个设置。注意:不是所有支持 SCT Error Recovery Control 的硬盘都能持久化保存设置。我手上的两款硬盘, HGST HC320 支持, 另一款 WD 红盘就不支持。
如果硬盘不支持持久化设置,或者你不希望把设置持久化到硬盘上,也可以在 smartd.conf 中使用 -l scterc,<READTIME>,<WRITETIME>
来让 smartd 在启动时去设置指定的硬盘。
-
HGST. Iterative Detection Read Channel Technology in Hard Disk Drives. 2008-11. https://web.archive.org/web/20181010031401/https://www.hgst.com/sites/default/files/resources/IDRC_WP_final.pdf ↩︎
最后修改于 2025-09-09