在 Linux 系统的浩瀚日志海洋中,dmesg 是一个独特的存在。它不像 nginx.log 那样记录 Web 请求,也不像 /var/log/messages 那样包罗万象。它是系统启动时最早亮起的灯塔,也是内核遇到麻烦时发出的第一声呼救。
无论你是运维工程师、开发者,还是在虚拟机里折腾环境的爱好者,读懂 dmesg 都是必备技能。今天,我们就来彻底拆解这只内核的"听诊器"。
一、dmesg 是什么?
dmesg(Display Message)用于打印和控制内核环形缓冲区(Kernel Ring Buffer)。
可以把这个缓冲区想象成内核的"草稿纸":
- 写在内存里:速度极快,不依赖磁盘。
- 环形的:空间有限(通常几百 KB 到几 MB)。写满了之后,新的内容会覆盖最老的内容。
- 源头最近:它记录的是内核自己说的话,包括 CPU 初始化、内存布局、USB 识别、驱动加载等。
正因为它的特殊性,dmesg 往往是排查硬件故障、驱动异常、启动卡顿的首选工具。
二、为什么需要 sudo?
在现代 Linux 发行版(Kernel 4.0+)中,直接运行 dmesg 可能会遇到权限拒绝:
bash
$ dmesg
dmesg: read kernel buffer failed: Operation not permitted
这是因为内核引入了 kernel.dmesg_restrict 参数(默认为 1)。为了防止非 root 用户读取内核地址布局(可用于绕过 KASLR 安全机制),访问权限被收紧了。
解决方案很简单:
bash
sudo dmesg
三、核心参数与实战用法
1. 让时间变得可读 (-T)
默认情况下,dmesg 的时间戳是系统启动后的秒数,对人类非常不友好:
[ 0.000000] Initializing cgroup subsys cpuset
加上 -T 参数,将其转换为可读的本地时间:
bash
sudo dmesg -T
输出示例:
[Tue Jun 25 10:30:01 2024] Initializing cgroup subsys cpuset
2. 过滤日志级别 (-l)
内核日志分为 8 个级别(0 最严重,7 最啰嗦)。排查问题时,我们通常只关心错误。
| 级别 | 名称 | 含义 |
|---|---|---|
| 0 | emerg | 系统不可使用 |
| 1 | alert | 必须立即处理 |
| 2 | crit | 严重条件 |
| 3 | err | 错误 |
| 4 | warn | 警告 |
| 5 | notice | 正常但重要 |
| 6 | info | 信息 |
| 7 | debug | 调试信息 |
只看错误和警告:
bash
sudo dmesg -l err,warn
3. 实时监控 (-w)
就像 tail -f 一样,你可以实时监控内核的动态。这在插入 USB 设备或加载内核模块时非常有用。
bash
sudo dmesg -w
插入一个 USB 设备,你会立刻看到内核识别硬件的过程。
4. 精准搜索 (grep)
结合 grep 是 dmesg 最常见的用法。
-
查看内存溢出 (OOM):
bashsudo dmesg | grep -i oom -
查看磁盘相关(虚拟机中常见):
bashsudo dmesg | grep -i "sda\|nvme" -
查看网卡 (虚拟机中排查 Virtio 驱动):
bashsudo dmesg | grep -i eth
5. 清空缓冲区 (-C)
有时为了做实验,你想清除旧的日志,只关注接下来的操作。
bash
sudo dmesg -C
⚠️ 注意:这会清空当前缓冲区,生产环境慎用。
四、虚拟机运维中的"杀手锏"
如果你在使用 KVM、VirtualBox 或 VMware,以下命令能帮你解决 80% 的网络和磁盘问题。
1. 排查 Virtio 驱动
虚拟机通常使用半虚拟化驱动来提高性能。如果磁盘或网络不通,首先检查驱动是否加载:
bash
sudo dmesg | grep -i virtio
如果没输出,说明内核可能没加载 virtio 模块。
2. 排查时间同步与时钟源
虚拟机时间漂移是常见问题。查看时钟源切换情况:
bash
sudo dmesg | grep -i "clocksource\|tsc"
3. 排查内存 Ballooning
如果宿主机调整了虚拟机内存,内核会有记录:
bash
sudo dmesg | grep -i balloon
【实战案例】当数据盘变成只读------透过 dmesg 看穿文件系统的"自我保护"
背景 :在某次系统的运维中,两台云主机的 /data 目录突然提示"Input/output error"(输入输出错误)。由于 /data 挂载了独立的数据盘,业务瞬间中断。
排查过程:
-
存储侧排查:管理员首先登录虚拟机管理平台,检查后端存储集群。发现相关卷集的性能曲线在故障发生时流量骤降为 0,但集群整体无告警,其他卷集业务正常。初步排除了存储集群全局性故障的可能性。
-
虚拟机侧定责 :此时,关键在于判断是"磁盘不能读写了"还是"文件系统不让读写了"。登录故障虚拟机,执行
dmesg命令:bashsudo dmesg -T | grep -i "error\|xfs" -
日志分析 :在
dmesg的输出中,发现了关键线索:- 大量的
I/O error指向具体的设备(如sdb1)。 - 紧接着出现了
XFS (sdb1): log I/O error和XFS_WANT_CORRUPTED_GOTO字样。 - 最关键的一行:
XFS (sdb1): Filesystem has been shut down due to log error (0x2).
- 大量的
结论 :
dmesg 清晰地揭示了真相------这不是底层磁盘的物理损坏,而是 XFS 文件系统的元数据损坏。
当 XFS 文件系统检测到元数据(Metadata)不一致时,为了保护数据不被进一步破坏,它会触发内核的保护机制,自动将文件系统切换为**只读(Read-Only)**模式。这就是为什么业务日志显示"输入输出错误",但存储侧却显示链路正常的根本原因。
解决方案 :
根据 dmesg 的定位,运维人员在卸载数据盘后,使用 xfs_repair -L 命令强制清空日志并修复元数据,最终成功恢复业务。
💡 经验总结 :
在云环境中遇到磁盘报错,不要急于断定是硬件坏了。
dmesg是区分"存储链路问题"和"文件系统逻辑问题"的分水岭。看到XFS_WANT_CORRUPTED_GOTO或EXT4-fs error,第一时间就该想到文件系统修复,而非盲目更换硬盘。
五、dmesg vs journalctl vs /var/log/messages
这是初学者最容易混淆的地方。我们用一张表来区分它们:
| 特性 | dmesg |
journalctl |
/var/log/messages |
|---|---|---|---|
| 数据来源 | 仅内核 | 内核 + 所有服务 | 经 syslog 筛选的系统日志 |
| 存储位置 | 内存 (RAM) | 二进制文件 (磁盘/内存) | 文本文件 (磁盘) |
| 重启后 | 丢失 | 可保留 (取决于配置) | 保留 |
| 主要用途 | 硬件、驱动、内核级错误 | 全系统综合排障 | 传统文本日志分析 |
简单记忆:
- 想看硬件 和驱动 问题 ->
dmesg - 想看某个服务 (如 Nginx、Docker)为什么挂了 ->
journalctl -u nginx - 想用
awk/grep批量处理历史文本 ->/var/log/messages
特别提示 :journalctl -k 可以看作是 dmesg 的持久化版本。如果你的系统开启了 journald 持久化存储,journalctl -k 能看到比 dmesg 更久之前的内核日志(因为 dmesg 的环形缓冲区满了会覆盖)。
六、总结
dmesg 是连接用户与内核的一座桥梁。虽然它只记录内核消息,但这正是它价值所在------当系统连用户态的服务都没起来时,只有 dmesg 能告诉你发生了什么。
正如我们在上述医疗云案例中看到的那样,dmesg 不仅能告诉我们"哪里错了",还能帮助我们判断"错在哪个层级"。这种能力在分秒必争的故障恢复中至关重要。
我的常用排障组合拳:
bash
sudo dmesg -T -l err,warn --color=always | less
记住这个命令,下次当你的 Linux 虚拟机启动变慢、磁盘消失或网卡失灵时,你将拥有直击问题本质的能力。