4、内核日志分析:内核日志级别、内核日志格式、常见内核错误解读

内核日志,说白了就是Linux内核的「日记本」。系统从加电到用户登录,内核干了什么、遇到了什么坑,全记在里面。我做了这么多年运维,每次系统出问题,第一反应就是翻内核日志。这玩意儿比什么监控工具都靠谱。

4.1 内核日志级别:从「废话」到「救命」

内核日志有8个级别,数字越小越紧急。我习惯把它们分成三档:

  • 0 (KERN_EMERG):系统要挂了,赶紧跑。比如内存彻底用完。
  • 1 (KERN_ALERT):必须马上处理。比如磁盘损坏。
  • 2 (KERN_CRIT):严重错误。比如硬件故障。
  • 3 (KERN_ERR):常见错误。驱动加载失败、文件系统报错。
  • 4 (KERN_WARNING):警告。不影响运行,但最好看看。
  • 5 (KERN_NOTICE):正常但重要的事件。比如网卡连上了。
  • 6 (KERN_INFO):信息。启动时各种「我加载了xxx」。
  • 7 (KERN_DEBUG):调试信息。平时看不到,得专门开。

我的经验:排查启动问题,重点看0-4级。5-7级信息量太大,容易看花眼。我曾经花了一下午看INFO日志,结果发现是ERR级别的磁盘报错被淹没了。

4.2 内核日志格式:一行看懂发生了什么

标准的dmesg输出长这样:

[    5.123456] sd 0:0:0:0: [sda] Starting disk
[    5.234567] EXT4-fs (sda1): mounted filesystem with ordered data mode
[    5.345678] systemd[1]: Starting Journal Service...

格式拆开看:

  • 时间戳:方括号里的数字,单位是秒。表示系统启动后多少秒发生的事件。
  • 来源:比如 sd 0:0:0:0 是SCSI磁盘驱动,EXT4-fs (sda1) 是文件系统。
  • 内容:具体干了什么。

嗯,这里要注意。时间戳不是绝对时间,是相对启动时间。如果你想知道具体几点几分,得用 dmesg -T 转成人类可读格式。

小技巧:用 dmesg -l err 只看错误级别。用 dmesg | grep -i error 搜关键词。我一般先 dmesg -l err,warn 扫一遍,再细看。

4.3 常见内核错误解读:这些报错你迟早会遇到

4.3.1 OOM Killer:内存杀手

你想想看,系统内存快用完了,内核会怎么办?它会挑一个「最不重要的进程」杀掉,腾出内存。这就是OOM Killer。

[  123.456789] Out of memory: Killed process 12345 (java) total-vm:1234567kB, anon-rss:890123kB, file-rss:0kB, shmem-rss:0kB

看到这个,别慌。先看谁被杀了。如果是Java、MySQL这类重要进程,说明内存真的不够了。我曾经遇到过一台服务器,跑着跑着MySQL被OOM杀了,查了半天发现是隔壁团队部署了个内存泄漏的Python脚本。

避坑指南:我曾经以为OOM Killer只杀「坏进程」,结果它杀的是「占用内存最多的进程」。如果你的数据库和缓存服务跑在一起,缓存服务可能先被干掉。

4.3.2 Kernel Panic:内核崩溃

这是最严重的错误。内核自己都跑不下去了,直接死给你看。

[  456.789012] Kernel panic - not syncing: Fatal exception
[  456.789013] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.10.0-8-amd64
[  456.789014] Hardware name: VMware Virtual Platform
[  456.789015] Call Trace:
[  456.789016]  dump_stack+0x6d/0x8a
[  456.789017]  panic+0x101/0x2d0
[  456.789018]  do_exit+0x7c/0xb80
[  456.789019]  do_group_exit+0x3a/0xa0

看到 Kernel panic 四个字,基本可以确定是硬件问题、驱动问题或者内核bug。我建议先看 Hardware nameCall Trace。Call Trace是函数调用栈,能告诉你崩溃前内核在干什么。

说白了,Kernel Panic就像系统突然「脑死亡」。没有商量余地,只能重启。但重启前记得拍个照(截图或拍照),不然重启后日志可能被覆盖。

4.3.3 文件系统错误:磁盘在求救

[  789.012345] EXT4-fs error (device sda1): ext4_find_entry:1456: inode #12345: comm ls: reading directory lblock 0
[  789.012346] Aborting journal on device sda1-8.
[  789.012347] EXT4-fs (sda1): Remounting filesystem read-only

这个报错很典型。文件系统发现数据不一致,为了保护剩余数据,自动把磁盘挂载成只读模式。这时候你写不了任何文件。

为什么会这样?可能是突然断电、磁盘坏道、或者文件系统本身有bug。我遇到过一台服务器,连续报这个错,最后发现是硬盘有物理坏道。

处理方法:先 umount 卸载,然后 fsck 修复。但注意,生产环境要谨慎,fsck可能丢数据。我一般先备份,再修复。

4.3.4 驱动加载失败:硬件不认了

[  234.567890] e1000e: probe of 0000:02:00.0 failed with error -2
[  234.567891] iwlwifi: No suitable firmware found!

驱动加载失败,常见原因有:

  • 内核没有对应的驱动模块
  • 固件文件缺失或版本不匹配
  • 硬件本身有问题

我建议先查 lspci -k 看硬件对应的驱动是什么,再用 modprobe 手动加载试试。如果报 No suitable firmware found,去 /lib/firmware 看看有没有对应的固件文件。

4.4 实战技巧:怎么高效看内核日志

我个人习惯用这几个命令组合:

# 只看错误和警告
dmesg -l err,warn

# 实时监控新日志
dmesg -w

# 搜索关键词
dmesg | grep -i "error\|fail\|panic"

# 看最后10条
dmesg | tail -10

# 带时间戳
dmesg -T | tail -20

你想想看,如果系统启动到一半卡住了,怎么查?我一般先 dmesg | tail -50 看最后50条,基本能定位到问题。如果日志被刷屏了,用 dmesg -l err 过滤。

总结一下:内核日志是系统启动的「黑匣子」。级别0-3是红色警报,4是黄色警告,5-7是日常记录。遇到问题先看错误级别,再看Call Trace,最后结合硬件信息判断。记住,日志不会骗人,但人可能会看漏。