dmesg 看不到最近 OOM 日志因缓冲区被覆盖或权限限制;驱动错误表现为 timeout/fail 等底层异常;需持久化日志并结合 /proc/meminfo、systemd-oomd 等综合分析。

为什么 dmesg 看不到最近的 OOM 日志?
因为 dmesg 默认只保留内核环形缓冲区里的内容,OOM 事件如果发生在很久以前,或者缓冲区被新日志刷掉,就查不到了。另外,系统启用 kdump 或 systemd-journald 后,部分日志可能被重定向或截断。
- 先用
dmesg -T | grep -i "out of memory"检查带时间戳的近期记录(-T要求 root 权限,否则显示相对时间) - 若无结果,立刻执行
dmesg -c清空当前缓冲区,再复现问题(比如跑个stress --vm 1 --vm-bytes 4G),避免日志被覆盖 - 注意:某些发行版(如 RHEL 8+/CentOS 8+)默认关闭
dmesg非 root 访问,需临时加kernel.dmesg_restrict=0到/etc/sysctl.conf并运行sysctl -p
dmesg 里驱动报错的关键特征是什么?
硬件驱动出问题时,dmesg 不会直接说“驱动坏了”,而是暴露底层行为异常:超时、DMA 错误、寄存器读写失败、probe 失败等。重点盯住 pci、nvme、ata、i2c、usb 这些前缀,以及 timeout、reset、failed、invalid 这类词。
- 例如:
nvme 0000:01:00.0: Device not ready; aborting reset—— NVMe 控制器卡死,不是线缆松动就是固件 bug -
ata1: softreset failed (device not ready)—— SATA 设备响应超时,优先检查电源/线材,再查smartctl -a /dev/sda - 用
dmesg | grep -E "(error|fail|warn|timeout)" | grep -i "pci\|nvme\|ata\|usb"快速过滤高危线索
如何让 dmesg 日志持久化并方便回溯?
默认的环形缓冲区最多存几 MB,重启即清空。要长期追踪硬件稳定性,必须把关键日志落地到文件,并设置合理轮转策略。
- 启用
rsyslog写入内核日志:确认/etc/rsyslog.conf有kern.* /var/log/kern.log这行,然后systemctl restart rsyslog - 或改用
journald:运行journalctl -k --since "2 weeks ago" | grep -i oom,它默认保留至少一周(取决于/etc/systemd/journald.conf中的MaxRetentionSec) - 禁止用
echo "" > /var/log/kern.log清日志——这会破坏 logrotate 的计数逻辑,应改用logrotate -f /etc/logrotate.d/rsyslog
OOM Killer 触发后,光看 dmesg 为什么不够?
dmesg 只告诉你“谁被杀了”,但不告诉你“为什么杀”和“杀得对不对”。它不会显示进程内存分布、cgroup 限制、page cache 占比这些关键上下文。
-
dmesg输出类似:Out of memory: Kill process 1234 (chrome) score 234 or sacrifice child—— 这里的score是 OOM 分数,数值越高越可能被选中,但分数计算依赖/proc/[pid]/oom_score_adj - 必须立刻补查:
cat /proc/meminfo(看MemAvailable是否真低)、grep -i "memory\|swap" /proc/1234/status(看被杀进程真实 RSS/VMS)、systemctl status systemd-oomd(确认是否启用了新版用户态 OOM 守护进程) - 注意:Linux 5.19+ 默认启用
systemd-oomd,它会绕过传统内核 OOM Killer,此时dmesg根本不会出现Out of memory字样,得查journalctl -u systemd-oomd
OOM 和驱动错误都容易被当成偶发故障忽略,但连续两次 dmesg 出现同一设备 timeout 或同一进程反复被杀,大概率是硬件接触不良、固件缺陷或内存泄漏,这时候别急着重启,先保存完整日志快照。



















