linux不自动记录读写延迟超时,需通过iostat -x查await与avgqu-sz、strace -t抓系统调用耗时、dmesg查硬件级timeout日志三者交叉验证。

Linux 没有“读写延迟超时记录”这种现成的日志或文件——它不自动记录哪些 I/O 请求超时了、在哪一秒、由哪个进程触发。 你看到的所谓“超时”,通常是应用层自己定义并报错(如 ETIMEDOUT、EAGAIN),或内核在极端情况下丢弃请求并打印 dmesg 日志。真要查,得从三个层面分别抓:I/O 延迟现状、系统调用级耗时、内核异常事件。
iostat -x 看实时 await 是否持续超标
这是第一道筛子,判断磁盘是否真在“慢”,而不是应用瞎报超时。
-
await是核心指标:它包含排队时间 + 设备服务时间,单位毫秒。HDD >10ms、SATA SSD >1ms、NVMe >0.5ms 就该警觉 - 别信
%util:NVMe 下基本失效;重点看avgqu-sz—— 持续 >1 表示请求在队列里堆着,不是设备慢,是压太狠 - 拆开看
r_await和w_await:如果写延迟飙升但读正常,大概率是日志刷盘、fsync 或 ext4 journal 模式拖慢 - 命令示例:
iostat -dx 1,盯住目标设备(如nvme0n1)那一行,连续观察 30 秒以上,避免瞬时抖动干扰
strace -T 抓具体进程的 read/write/fsync 耗时
当 iostat 显示延迟高,但不确定是哪个操作卡住时,用 strace -T 直接看系统调用真实耗时——它能暴露应用层感知到的“超时前最后一秒”发生了什么。
- 必须加
-T(显示耗时)+-tt(微秒时间戳)+-e trace=read,write,fsync,openat(只抓 I/O 相关) - 重点关注:
read(3, ...)=4096这类输出,括号里数字单位是秒;>0.3s 的 read/write、>0.1s 的 fsync 都值得怀疑 - 如果看到
read(5, ...) = -1 EAGAIN,而应用设了 3 秒 timeout,说明内核确实等了快到极限才返回,不是应用误判 - 安全做法:
timeout 60 strace -T -tt -e trace=io -p $PID -o /tmp/strace.log,避免长跑影响业务
dmesg 查内核是否主动丢弃或重试 I/O
真正的硬件级超时(比如 NVMe 控制器响应超时、RAID 卡掉盘)会触发内核打印警告,这类信息只存在 dmesg 缓冲区,不落盘、不进 syslog,默认滚动丢失。
- 运行
dmesg -T | grep -i "timeout\|error\|nvme\|ata\|reset\|fail",重点扫含timeout或command timeout的行 - 典型输出:
[Wed Jul 9 17:22:11 2026] nvme nvme0: I/O 12345 timeout, reset controller—— 这是硬超时,已绕过所有上层逻辑 - 如果发现大量
blk_update_request: I/O error,说明设备返回失败而非超时,问题可能在链路(线缆、背板)或固件 - 注意:dmesg 缓存有限,出问题后要尽快查,重启会清空
真正难的不是找到某次超时,而是区分「应用设了 1 秒 timeout 却等了 1.2 秒」和「内核根本没响应、直接卡死」——前者靠 strace -T 和 iostat 对齐时间戳,后者只能靠 dmesg 和 blktrace 往底层挖。没人帮你记“超时记录”,你得自己搭这三根线去交叉验证。











