4. dmesg 实战:存储设备错误日志解读

当文件系统出现异常时,dmesg 是内核直接向运维人员输出的“第一手诊断报告”。本章聚焦三类最常见的存储设备级错误:磁盘坏道、控制器重置和链路抖动,通过真实日志片段与内核行为分析,建立从错误现象到根因定位的完整链路。

核心原则:dmesg 日志按时间顺序排列,错误通常伴随 ata、sd、scsi、blk_update_request 等关键字。先定位 I/O error 或 failed command 时间戳,再向上追溯前 5~10 行寻找根因。

4.1 磁盘坏道(Bad Block / Media Error)

磁盘坏道是存储介质物理损坏的典型表现。内核在读写失败时会记录扇区地址和错误码,并可能触发重映射或离线操作。

4.1.1 典型日志特征

[Mon May 15 10:23:45 2025] sd 0:0:0:0: [sda] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=0s
[Mon May 15 10:23:45 2025] sd 0:0:0:0: [sda] tag#0 Sense Key : Medium Error [current]
[Mon May 15 10:23:45 2025] sd 0:0:0:0: [sda] tag#0 Add. Sense: Unrecovered read error - auto reallocate failed
[Mon May 15 10:23:45 2025] sd 0:0:0:0: [sda] tag#0 CDB: Read(10) 28 00 00 3a 5f 80 00 00 08 00
[Mon May 15 10:23:45 2025] blk_update_request: I/O error, dev sda, sector 3827712 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 0
日志字段含义排查方向
Sense Key: Medium ErrorSCSI 感知键,明确指示介质错误确认物理坏道,需检查 SMART 属性
Unrecovered read error读取不可恢复,且自动重分配失败磁盘备用扇区已耗尽,需立即更换
sector 3827712逻辑块地址(LBA)转换为 CHS 或使用 badblocks 扫描
op 0x0:(READ)操作类型为读取写错误通常伴随 WRITE 标记
实战技巧:使用 smartctl -l error /dev/sda 查看磁盘内部错误日志,与 dmesg 中的扇区号交叉验证。若 SMART 的 Reallocated_Sector_Ct 持续增长,说明坏道正在扩散。

4.1.2 坏道影响链路图

下图展示了一次读请求命中坏道后,从块层到 SCSI 层的完整错误传递路径:

磁盘坏道错误传递路径 应用读请求 VFS / 块层 SCSI 中层 磁盘驱动 介质错误 Sense Key 构造 I/O error 上报 应用返回 EIO 关键点:dmesg 中 Sense Key 由 SCSI 中层构造,blk_update_request 由块层输出 两个日志行的时间戳差通常 < 1ms,可用于确认错误是否来自同一 I/O

4.2 控制器重置(Controller Reset / EH Reset)

当磁盘长时间无响应或返回异常状态时,SCSI 错误处理程序(EH)会发起控制器重置。这是内核的“最后手段”,通常意味着链路或固件层面出现严重问题。

4.2.1 典型日志序列

[Mon May 15 11:05:12 2025] ata1.00: exception Emask 0x10 SAct 0x0 SErr 0x4050000 action 0x6 frozen
[Mon May 15 11:05:12 2025] ata1.00: irq_stat 0x00000040, connection status changed
[Mon May 15 11:05:12 2025] ata1.00: failed command: READ DMA EXT
[Mon May 15 11:05:12 2025] ata1.00: cmd 25/00:08:00:00:00/00:00:00:00:00/e0 tag 0 dma 4096 in
[Mon May 15 11:05:12 2025] ata1.00: status: { DRDY ERR }
[Mon May 15 11:05:12 2025] ata1.00: error: { UNC }
[Mon May 15 11:05:13 2025] ata1: softreset failed, retrying in 5 secs
[Mon May 15 11:05:18 2025] ata1: softreset succeeded, device ready
日志行内核行为运维响应
exception Emask 0x10EH 捕获异常,冻结端口记录时间戳,准备收集更多上下文
connection status changed链路状态变化,可能为线缆松动检查物理连接、背板、HBA 卡
softreset failed软重置失败,进入重试等待若连续失败,需考虑硬件更换
softreset succeeded重置成功,设备恢复检查后续 I/O 是否正常,评估影响
注意:控制器重置期间,该链路上所有未完成的 I/O 都会被中止并重试。频繁重置(每小时超过 3 次)会显著降低 IOPS,并可能导致文件系统元数据损坏。

4.2.2 控制器重置状态机

ATA 控制器重置状态机 正常 I/O 异常捕获 端口冻结 软重置 重置成功 硬重置 / 复位

4.3 链路抖动(Link Jitter / PHY Event)

链路抖动指物理层信号不稳定,导致连接反复断开重连。SAS/SATA 背板、线缆、HBA 卡或电源问题都可能引发。dmesg 中通常表现为 link down / link up 交替出现。

4.3.1 典型日志特征

[Mon May 15 12:01:22 2025] ata2: link is slow to respond, please be patient (ready=0)
[Mon May 15 12:01:27 2025] ata2: softreset failed (1st FIS failed)
[Mon May 15 12:01:32 2025] ata2: link is slow to respond, please be patient (ready=0)
[Mon May 15 12:01:37 2025] ata2: COMRESET failed (errno=-16)
[Mon May 15 12:01:42 2025] ata2: link is slow to respond, please be patient (ready=0)
[Mon May 15 12:01:47 2025] ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[Mon May 15 12:01:52 2025] ata2.00: configured for UDMA/133
[Mon May 15 12:01:52 2025] ata2: EH complete
链路抖动 vs 控制器重置:链路抖动发生在物理层(PHY),日志以 link is slow to respond、COMRESET 为主;控制器重置发生在逻辑层,以 exception Emask、softreset 为主。两者可能同时出现,但根因不同。

4.3.2 链路抖动排查清单

  • 物理层检查:重新插拔线缆,更换已知正常的线缆测试;检查背板金手指是否氧化。
  • 速率协商:日志中 SATA link up 1.5 Gbps 若低于预期(如 6.0 Gbps),说明链路质量差,速率自动降级。
  • 电源域:检查磁盘供电电压,使用 smartctl -a 查看 Voltage 属性(部分 SAS 盘支持)。
  • HBA 固件:更新 HBA 卡固件,部分厂商在发行说明中会提及链路稳定性修复。

4.3.3 链路抖动时间线

链路抖动事件时间线 link down T+0s COMRESET T+5s COMRESET T+10s link up T+25s EH complete T+30s 从 link down 到 EH complete 耗时 30 秒,期间该链路所有 I/O 被阻塞 若抖动频率 > 1 次/分钟,建议立即切换备件或迁移数据

4.4 综合排查流程

当 dmesg 中同时出现多种错误类型时,按以下优先级排查:

  1. 先物理后逻辑:链路抖动 > 控制器重置 > 坏道。物理层问题会引发上层所有错误。
  2. 先全局后局部:检查是否所有磁盘都出现错误(背板/电源问题),还是单盘(坏道/固件)。
  3. 先统计后细节:使用 dmesg --level=err,warn | grep -E 'ata|sd|scsi' | wc -l 统计错误频率,再逐行分析。
推荐工具链:
dmesg -T 将时间戳转为可读格式;
journalctl -k -p err --since "1 hour ago" 查看最近 1 小时内核错误;
smartctl -l selftest /dev/sda 查看磁盘自检历史。