简介:这是一份面向Linux运维工程师与系统管理员的故障排查参考资料,聚焦系统死机或崩溃后如何有效采集与分析现场信息,帮助判断问题源于硬件故障还是应用程序缺陷。文档围绕Core dump、Diskdump、Netdump三种机制展开,分别覆盖应用级内存转储、单机内核转储以及跨网络远程转储的配置思路与关键命令,适合具备一定Linux基础、需要提升故障定位能力的读者参考。资源包共1个文件,为doc格式文档,压缩包约47KB,内容紧凑、便于随查随用。目前已有527人学习下载,说明其在运维排障场景中具有一定实用价值。读者可从中获得三类崩溃信息获取方式的完整梳理,包括core文件生成路径设置、diskdump保留分区初始化与initrd重建、netdump服务端与客户端配置要点,以及网卡netpoll支持判断等细节,有助于在系统异常后快速留存关键现场数据,缩短故障分析与修复周期。
1. 线上 Linux 死机那一刻,先别急着按电源键
凌晨两点被告警叫醒,SSH 连不上、ping 不通、业务全挂,机房那边说机器还在通电但屏幕没有任何反应——这就是典型的 Linux 死机现场。很多人第一反应是长按电源键重启,但这一按,内存里的现场就全没了,事后想复盘到底是 OOM、IO hang 还是内核 panic,只能靠猜。Linux 死机处理的核心不是「怎么重启」,而是「在重启之前,尽可能把现场信息捞出来,同时判断这次死机属于哪一类」。这篇笔记面向的是真正管过线上服务器的人:你手上有 root、有 IPMI 或云控制台、有监控,但机器已经失去响应,你要在最短时间内做出正确动作。下面按「先分类、再取证、后恢复」的顺序,把每一步的命令、参数和踩过的坑讲清楚,新手能照着敲,熟手能对一下自己的应急手册有没有漏项。
2. 先分清 Linux 死机的四种类型:别把 IO hang 当内核 panic 处理
Linux 死机不是一个单一状态,处理方式完全取决于它卡在哪一层。我一般把它分成四类:用户态卡死(系统还在跑,只是某个服务无响应)、内核 panic(内核自己崩了)、IO hang(磁盘或网络存储不返回)、以及硬件级死机(CPU、内存、主板出问题)。分错类型,后面的取证动作全是白费。
2.1 从控制台和指示灯做第一轮判断
如果你能碰到物理机或云厂商的 VNC 控制台,先看三件事:屏幕有没有输出、键盘 Caps Lock 灯能不能切换、机器风扇和硬盘灯的状态。Caps Lock 灯能切换,说明内核还在调度中断,大概率是用户态或部分 IO 卡死;灯完全没反应,基本是内核 panic 或硬件死机。云主机没有物理灯,就看控制台的「重启」「强制关机」按钮是否还能响应,以及云监控里 CPU、内存曲线是断崖还是持续高位。
# 如果你还能通过带外管理(IPMI/iDRAC/云控制台)进入,先看内核日志缓冲区 dmesg -T | tail -n 100 # -T 把内核时间戳转成可读时间,tail 看最后 100 行,panic 前一般会有 Oops 或 BUG 字样 # 看上一次启动到现在有没有硬件报错 journalctl -k -b -1 -p err # -k 只看内核消息,-b -1 看上一次启动,-p err 只看 error 及以上级别这两条命令的前提是系统还能响应。如果 SSH 已经断了,就要靠串口 console 或者 kdump 留下的 vmcore 文件。参数上,dmesg -T的时间戳依赖系统时钟,如果死机前时钟被 NTP 跳变过,时间会对不上,这点在跨时区机房里要特别注意。
2.2 用 Magic SysRq 在不重启的前提下抓现场
Linux 内核内置了一组 Magic SysRq 组合键,通过/proc/sys/kernel/sysrq控制。它的价值在于:即使系统已经卡到无法登录,只要内核还能响应键盘中断,你就能强制同步磁盘、导出进程状态、甚至安全重启。常见做法是在物理机键盘上按Alt + SysRq + 字母,云主机则通过串口发送对应字符。
# 先确认 sysrq 功能是否开启,1 表示全部开启 cat /proc/sys/kernel/sysrq # 临时开启全部功能(重启后失效) echo 1 > /proc/sys/kernel/sysrq # 常用组合(物理键盘 Alt+SysRq+字母,串口发对应字符) # m - 导出内存信息到控制台 # t - 导出当前所有进程状态 # w - 导出不可中断(D 状态)进程 # s - 同步所有挂载的文件系统 # u - 重新以只读方式挂载 # b - 立即重启这里的关键是顺序:s同步、u只读挂载、b重启,也就是常说的s-u-b。直接按b会丢数据,先s再u能把文件系统损坏概率降到最低。m和t是取证用的,输出会打到当前控制台,如果控制台没接串口日志,这些信息就丢了,所以生产机器一定要配串口重定向或 kdump。
2.3 判断是不是 IO hang:D 状态进程是核心线索
IO hang 最迷惑人,因为 CPU 可能很闲、内存也正常,但所有涉及磁盘的操作全部卡住。典型现象是df卡住、ls卡住、ps里一堆进程处于D(不可中断睡眠)状态。这时候重启往往也重启不了,因为关机流程要卸载文件系统,一样会卡在 IO 上。
# 统计 D 状态进程数量,超过 5 个就要警惕 ps -eo state,pid,comm | awk '$1=="D"' # 看这些进程卡在哪个内核调用上 cat /proc/<PID>/stack # 输出会显示内核栈,如果停在 io_schedule、blk_mq 之类,基本确认是块设备 IO hang # 看块设备队列和 IO 统计 iostat -x 1 5 # -x 显示扩展统计,1 5 表示每秒采样一次共 5 次,%util 接近 100 且 await 极高就是 IO 瓶颈/proc/<PID>/stack需要 root 权限,且部分内核配置下普通进程看不到。如果输出是空的,说明该进程不在内核态,或者内核没开CONFIG_STACKTRACE。这时候退一步看iostat和dmesg里有没有blocked for more than 120 seconds这类告警,那是内核 hung task 检测器在报 IO 卡死。
3. 死机现场取证:kdump、vmcore 和日志三件套怎么配
死机处理最怕「重启完什么都没留下」。要能事后分析,必须在机器还活着的时候就把 kdump 配好。kdump 的原理是:内核 panic 时,用一块预留内存启动一个「捕获内核」,把崩溃内核的完整内存镜像(vmcore)写到磁盘或网络。没有它,你只能靠串口日志里那几行 Oops。
3.1 配置 kdump 并验证 vmcore 能落盘
不同发行版配置方式略有差异,但核心是给捕获内核预留内存、指定 vmcore 输出路径。以常见的 systemd 系发行版为例:
# 安装 kexec-tools(kdump 依赖它加载捕获内核) yum install -y kexec-tools # RHEL/CentOS 系 apt install -y kdump-tools # Debian/Ubuntu 系 # 预留内存,编辑 grub 配置,在 crashkernel 参数里指定大小 # 一般 128M 起步,内存大的机器给 512M 更稳 grep crashkernel /proc/cmdline # 启动 kdump 服务 systemctl enable --now kdump systemctl status kdump # 验证:手动触发一次内核崩溃(生产环境慎用!) echo c > /proc/sysrq-trigger # 机器会 panic 并重启,重启后检查 /var/crash 下有没有 vmcore ls -lh /var/crash/crashkernel=auto在新内核里能自动算预留大小,但老内核上经常算得太小导致捕获内核起不来。我一般直接写死crashkernel=512M,宁可浪费一点内存。echo c > /proc/sysrq-trigger是强制触发 panic,只能在测试机做,线上做之前确认业务已切走。
3.2 用 crash 工具读 vmcore 定位崩溃点
拿到 vmcore 后,用crash工具配合对应版本的内核调试符号(vmlinux)分析。调试符号要和崩溃内核版本严格一致,否则解析会错位。
# 安装 crash 和内核调试符号 yum install -y crash kernel-debuginfo-$(uname -r) # 进入 crash 交互界面 crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/vmcore # 常用命令 # bt - 查看崩溃时的调用栈 # log - 查看内核日志缓冲区 # ps - 查看崩溃瞬间的进程列表 # files - 查看打开的文件 # kmem -i - 查看内存使用概况bt是最关键的一条,它会打印崩溃时的函数调用链。如果栈顶是panic、oops、BUG,往下看是谁调用的。常见的是驱动 bug、内存越界、空指针。log能看到 panic 前最后的内核输出,比串口日志更完整,因为串口可能丢字符。
3.3 日志三件套:journalctl、dmesg、sar 的取数顺序
不是每次死机都有 vmcore,很多时候只能靠日志。取数顺序我一般是这样:先journalctl -b -1看上次启动的完整日志,再dmesg看内核环形缓冲区,最后sar看死机前的资源曲线。
# 看上一次启动的全部日志,按时间倒序 journalctl -b -1 --no-pager | tail -n 500 # 只看内核相关的 error journalctl -k -b -1 -p err --no-pager # 看死机前的 CPU、内存、IO 历史(需提前装 sysstat) sar -u -f /var/log/sa/sa15 # 15 号那天的 CPU sar -r -f /var/log/sa/sa15 # 内存 sar -b -f /var/log/sa/sa15 # IOjournalctl -b -1依赖 journal 持久化配置,如果/var/log/journal没建,日志只存在内存里,重启就没了。sar依赖sysstat服务,默认可能没开,生产机器建议提前启用并保留至少 7 天数据。这三样凑齐,基本能还原死机前几分钟发生了什么。
4. 避坑与排查:死机处理里最容易翻车的五个动作
这一章是我自己踩过和看别人踩过的坑,每条按「现象 → 原因 → 解决」写,照着对一遍能省不少后悔药。
4.1 现象:重启后 vmcore 没生成,/var/crash 是空的
原因通常是三种:crashkernel预留内存太小,捕获内核起不来;/var/crash所在分区空间不够,写不下;或者 kdump 服务根本没设成开机自启,panic 时没人接。解决:先systemctl status kdump确认服务状态,再grep crashkernel /proc/cmdline看预留大小,最后df -h /var/crash看空间。三个都正常还不行,就看/var/log/kdump.log,里面会写捕获内核启动失败的具体原因。
4.2 现象:Magic SysRq 按了没反应
原因一般是/proc/sys/kernel/sysrq被设成了 0,或者云主机串口没开 SysRq 透传。有些发行版默认只开部分功能(比如值 176),b能用但t不能用。解决:先cat /proc/sys/kernel/sysrq确认值,需要全部功能就echo 1。云主机要在控制台的串口设置里确认「发送 SysRq」选项已开,否则你发的字符到不了内核。
4.3 现象:IO hang 时执行 reboot 卡住,机器既不死也不活
原因是关机流程要卸载文件系统,而文件系统正卡在 IO 上,umount永远等不到返回。解决:不要用reboot,用echo b > /proc/sysrq-trigger强制立即重启,跳过所有卸载流程。代价是可能丢未落盘数据、文件系统需要 fsck,但比一直卡着强。如果连 SysRq 都没反应,只能带外强制断电,这是最后手段。
4.4 现象:dmesg 里全是「blocked for more than 120 seconds」,但不知道谁卡的
原因是内核 hung task 检测器只报「有任务卡了 120 秒」,不直接说是哪个设备。解决:结合ps -eo state,pid,comm | awk '$1=="D"'找到 D 状态进程,再cat /proc/<PID>/stack看内核栈。如果栈里出现blk_mq、scsi、nfs等字样,就能定位到具体是本地盘、SAN 还是网络存储。NFS 卡死尤其常见,mount时加soft,timeo=30能避免无限等待。
4.5 现象:内存看着没满,但系统突然卡死,日志里有 OOM
原因是 OOM killer 触发时可能杀错了进程,或者内存碎片导致分配失败但free显示还有余量。解决:看journalctl -k | grep -i oom确认有没有 OOM 记录,再看/proc/meminfo里的MemAvailable而不是MemFree。MemFree低不代表不够用,MemAvailable才是真实可用。如果确认是 OOM,调vm.overcommit_memory和vm.panic_on_oom要谨慎,前者设 2 会让分配更严格,后者设 1 会让 OOM 直接 panic 触发 kdump,适合需要抓现场的机器。
5. 把死机处理变成可复现流程:串口日志、监控联动和一次演练
前面讲的都是单点动作,真正让死机处理不慌的,是把它变成一套可复现的流程。我的习惯是:每台生产机器上线前,串口日志重定向、kdump、sysstat 三样必须配好,缺一样都不让进池子。串口日志的价值在于,内核 panic 时哪怕 kdump 没起来,串口也能把 Oops 那几行打出来,这是最后的黑匣子。
# 配置串口日志重定向到文件(以 GRUB 为例) # 编辑 /etc/default/grub,在 GRUB_CMDLINE_LINUX 里加: # console=tty0 console=ttyS0,115200n8 # 然后更新 grub 并重启 grub2-mkconfig -o /boot/grub2/grub.cfg # Debian/Ubuntu 用 update-grub # 用 screen 或 minicom 接串口,把输出落盘 screen -L -Logfile /var/log/serial-$(date +%F).log /dev/ttyS0 115200 # -L 开启日志,-Logfile 指定路径,/dev/ttyS0 是串口设备,115200 是波特率参数上,console=tty0 console=ttyS0,115200n8里的n8是无校验、8 数据位,这是串口标准配置,改错会乱码。screen -L的日志文件要定期轮转,否则会撑满磁盘。云主机一般用厂商提供的串口日志功能,不用自己接 screen,但要在控制台里确认「串口日志」已开启并设置了保留时长。
监控联动这块,我一般会在监控系统里加两条规则:一是node_load1超过核数 3 倍且持续 5 分钟告警,二是node_procs_blocked(D 状态进程数)大于 5 告警。这两条能在系统彻底死透之前给出预警,留出取证时间。告警触发后,自动化脚本可以先抓一份dmesg、ps、iostat快照存到远端,再通知人介入。
最后说演练。kdump 配了不代表能用,我见过太多「配了但 panic 时没生成 vmcore」的案例。建议每季度在测试机做一次echo c > /proc/sysrq-trigger,确认 vmcore 能落盘、crash 能解析、串口日志有输出。演练时把整个流程走一遍:触发 panic → 等重启 → 检查/var/crash→ 用 crash 读bt→ 确认能定位到触发点。走通了,真出事时才不会手忙脚乱。我自己就吃过亏,一台机器配了 kdump 但从没验证过,真 panic 时发现crashkernel预留太小,捕获内核根本没起来,白白丢了一次现场。从那以后,验证 kdump 成了我上线检查清单里的固定项。希望帮到你。
本文还有配套的精品资源,点击获取