最近数据库服务器备机升级网卡驱动版本以及大数据有个别设备直接crash重启了,查看日志也查不到当时时间点的日志,查看kdump是开启了的,但是数据库的kdump不知道为啥没有生成crash日志,为了发现问题并找出问题,我在虚机上也配置了kdump学习下它的工作原理和实际应用。
kdump简介
Linux的内核十分稳定,但仍不可避免地会遇到崩溃的情况,获取内核崩溃时的内存镜像,有助于分析系统在崩溃前发生了什么,分析原因并修复错误,进而改进系统的稳定性。
Kdump 用于对内存镜像的转储,它不但可以转储内存镜像到本地硬盘,还可以将内存镜像通过 NFS, SSH 等协议转储到不同机器的设备上。
Kdump 分为两个组件: Kexec 和 Kdump。
Kexec 是一种内核的快速启动工具,可以使新的内核在正在运行的内核(生产内核)的上下文中启动,而不需要通过耗时的 BIOS 检测,方便内核开发人员对内核进行调试。
Kdump 是一种有效的内存转储工具,启用 Kdump 后,生产内核将会保留一部分内存空间,用于在内核崩溃时通过 Kexec 快速启动到新的内核,这个过程不需要重启系统,因此可以转储崩溃的生产内核的内存镜像。
试验环境:
-
[root@test-server upload]# lsb_release -a
-
LSB Version: :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
-
Distributor ID: RedHatEnterpriseServer
-
Description: Red Hat Enterprise Linux Server release 6.8 (Santiago)
-
Release: 6.8
-
Codename: Santiago
-
[root@test-server upload]# uname -a
-
Linux test-server 2.6.32-642.el6.x86_64 #1 SMP Wed Apr 13 00:51:26 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux
-
[root@test-server upload]#
一、查看有没有安装kexec-tools这个rpm包,没有就rpm或者yum方式将它安装上。
-
[root@test-server upload]# rpm -qa|grep kexec
-
kexec-tools-2.0.0-300.el6.x86_64
二、在grub中为kdump kernel 配置保留的内存空间,修改/boot/grub/grub.conf 并且在kernel行增加crashkernel=[size]M (or crashkernel=auto)
crashkernel参数格式是:br/>crashkernel=nn[KMG]@ss[KMG]
nn表示要为crashkernel预留多少内存
ss表示为crashkernel预留内存的起始位置
我的grub.conf配置文件配置
-
[root@test-server upload]# cat /boot/grub/grub.conf
-
\# grub.conf generated by anaconda
-
\#
-
\# Note that you do not have to rerun grub after making changes to this file
-
\# NOTICE: You have a /boot partition. This means that
-
\# all kernel and initrd paths are relative to /boot/, eg.
-
\# root (hd0,0)
-
\# kernel /vmlinuz-version ro root=/dev/mapper/vg_testserver-LogVol01_root
-
\# initrd /initrd-[generic-]version.img
-
\#boot=/dev/sda
-
default=1
-
timeout=5
-
splashimage=(hd0,0)/grub/splash.xpm.gz
-
hiddenmenu
-
title Red Hat Enterprise Linux Server (2.6.32-642.el6.x86_64.debug)
-
root (hd0,0)
-
kernel /vmlinuz-2.6.32-642.el6.x86_64.debug ro root=/dev/mapper/vg_testserver-LogVol01_root rd_NO_LUKS rd_LVM_LV=vg_testserver/LogVol00_swap rd_LVM_LV=vg_testserver/LogVol01_root rd_NO_MD crashkernel=128M@48M LANG=zh_CN.UTF-8 KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
-
initrd /initramfs-2.6.32-642.el6.x86_64.debug.img
-
title Red Hat Enterprise Linux 6 (2.6.32-642.el6.x86_64)
-
root (hd0,0)
-
kernel /vmlinuz-2.6.32-642.el6.x86_64 ro root=/dev/mapper/vg_testserver-LogVol01_root rd_NO_LUKS rd_LVM_LV=vg_testserver/LogVol00_swap rd_LVM_LV=vg_testserver/LogVol01_root rd_NO_MD crashkernel=128M@48M LANG=zh_CN.UTF-8 KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
-
initrd /initramfs-2.6.32-642.el6.x86_64.img
-
[root@test-server upload]#
注意:这里grub.conf配置文件中如果crashkernel=auto 对于小内存(我自己测试的虚机内存是1G)会出现kdump服务启动不起来,并且在系统messages日志里出现“kdump: No crashkernel parameter specified for running kernel”,这时需要你手动的指定crashkernel的值
系统的内存 <= 8 GB --> crashkernel=128M (后面的可以省略)
系统的内存> 8 GB 但是<= 16 GB --> crashkernel=256M
系统内存> 16GB --> crashkernel=512M
三、kdump配置文件将系统崩溃后的文件默认放在了/var/crash中,crash文件既可以放在本地也可以在崩溃后传送到远端服务器,我只在本地分析所以我就使用默认配置了。
-
[root@test-server upload]# egrep -v '^$|^#' /etc/kdump.conf
-
path /var/crash
-
core_collector makedumpfile -c --message-level 1 -d 31
四、启用kdump后台程序
4.1 检查和确保kernel命令行包括了kdump配置和为kdump保留了内存转储空间
-
[root@test-server upload]# cat /proc/cmdline
-
ro root=/dev/mapper/vg_testserver-LogVol01_root rd_NO_LUKS rd_LVM_LV=vg_testserver/LogVol00_swap rd_LVM_LV=vg_testserver/LogVol01_root rd_NO_MD crashkernel=128M@48M LANG=zh_CN.UTF-8 KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
-
[root@test-server upload]#
4.2 将kdump服务设置为开机自启动
-
[root@test-server upload]# chkconfig kdupmp on
-
[root@test-server upload]# chkconfig --list|grep kdump
-
kdump 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭
[root@test-server upload]#
4.3 启用kdump后台进程
-
[root@test-server upload]# service kdump start
-
Starting kdump: [确定]
五、grub配置文件和kdump服务配置好后需要重启下系统生效
[root@test-server upload]# reboot
六、检查kdump状态确保kdump服务是在运行的
-
[root@test-server upload]# service kdump status
-
Kdump is operational
-
[root@test-server upload]#
七、测试模拟kdump
-
[root@test-server upload]# echo 1 > /proc/sys/kernel/sysrq
-
[root@test-server upload]# echo c > /proc/sysrq-trigger
八、使用一下命令触发内核的崩溃,在/var/crash目录会有一个内核崩溃时间点生成的内核镜像文件
-
[root@test-server upload]# ls -l /var/crash/
-
总用量 4
-
drwxr-xr-x. 2 root root 4096 12月 19 05:04 127.0.0.1-2017-12-19-05:04:30
-
[root@test-server upload]#
kdump配置完成,现在需要对crash文件进行分析
Crash 是由 David Anderson开发维护的分析内存转储文件的工具,它可以分析多种工具产生的内存转储文件。
一、检查是否安装crash rpm安装包
-
[root@test-server upload]# type crash
-
crash is hashed (/usr/bin/crash)
-
[root@test-server upload]# rpm -qf /usr/bin/crash
-
crash-7.1.0-6.el6.x86_64
-
[root@test-server upload]#
二、检查是否安装kernel-debuginfo安装包
-
[root@test-server upload]# rpm -qa|grep kernel-debuginfo
-
kernel-debuginfo-common-x86_64-2.6.32-642.el6.x86_64
-
kernel-debuginfo-2.6.32-642.el6.x86_64
三、如果步骤2没有安装对应的kernel-debuginfo rpm包,需要从网上进行下载,ISO镜像里是没有这两个安装包的。
3.1首先确认自己的内核版本
-
[root@test-server upload]# uname -r
-
2.6.32-642.el6.x86_64
-
[root@test-server upload]#
3.2 根据内核版本下载对应版本的kernel-debuginfo rpm包,下载网址是http://debuginfo.centos.org/6/x86_64/,环境不一样下载的安装包版本和网址URL都不一样
3.3 通过SFTP或者FTP等工具将安装包传到对应的机器上
3.4 安装kernel-debuginfo rpm包
-
[root@test-server upload]# rpm -ivh kernel-debuginfo*
-
warning: kernel-debuginfo-2.6.32-642.el6.x86_64.rpm: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
-
Preparing... ########################################### [100%]
-
1:kernel-debuginfo-common########################################### [ 50%]
-
2:kernel-debuginfo ########################################### [100%]
四、使用如下命令即可开始使用 Crash 分析内存转储文件,其中第一个参数为带有调试信息的内核, 第二个参数为某次崩溃产生的内存转储文件
-
[root@test-server upload]# crash /usr/lib/debug/lib/modules/2.6.32-642.el6.x86_64/vmlinux /var/crash/127.0.0.1-2017-12-19-05\:04\:30/vmcore
-
crash 7.1.0-6.el6
-
Copyright (C) 2002-2014 Red Hat, Inc.
-
Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation
-
Copyright (C) 1999-2006 Hewlett-Packard Co
-
Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited
-
Copyright (C) 2006, 2007 VA Linux Systems Japan K.K.
-
Copyright (C) 2005, 2011 NEC Corporation
-
Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc.
-
Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
-
This program is free software, covered by the GNU General Public License,
-
and you are welcome to change it and/or distribute copies of it under
-
certain conditions. Enter "help copying" to see the conditions.
-
This program has absolutely no warranty. Enter "help warranty" for details.
-
GNU gdb (GDB) 7.6
-
Copyright (C) 2013 Free Software Foundation, Inc.
-
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
-
This is free software: you are free to change and redistribute it.
-
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
-
and "show warranty" for details.
-
This GDB was configured as "x86_64-unknown-linux-gnu"...
-
WARNING: kernel version inconsistency between vmlinux and dumpfile
-
KERNEL: /usr/lib/debug/lib/modules/2.6.32-642.el6.x86_64/vmlinux
-
DUMPFILE: /var/crash/127.0.0.1-2017-12-19-05:04:30/vmcore [PARTIAL DUMP]
-
CPUS: 1
-
DATE: Tue Dec 19 05:04:27 2017
-
UPTIME: 00:02:22
-
LOAD AVERAGE: 0.15, 0.13, 0.05
-
TASKS: 205
-
NODENAME: test-server
-
RELEASE: 2.6.32-642.el6.x86_64
-
VERSION: #1 SMP Wed Apr 13 00:51:26 EDT 2016
-
MACHINE: x86_64 (2294 Mhz)
-
MEMORY: 1 GB
-
PANIC: "SysRq : Trigger a crash"
-
PID: 2236
-
COMMAND: "bash"
-
TASK: ffff88003e268ab0 [THREAD_INFO: ffff880039cf8000]
-
CPU: 0
-
STATE: TASK_RUNNING (SYSRQ)
其中各项参数的意义为:
KERNEL: 表示调试用内核的位置和版本信息;
DUMPFILE: 表示所分析的内存转储镜像
CPUS: 表示本机的 CPU 数目;
DATE: 表示内核崩溃发生的时间;
UPTIME: 表示内核已正常运行的时间;
LOAD AVERAGE: 表示内核崩溃时系统的负载;
TASKS: 表示内核崩溃时系统运行的任务数;
NODENAME: 表示内核崩溃的机器的主机名;
RELEASE: 表示内核的发布版本;
VERSION: 表示内核的其他版本信息
MACHINE: 表示 CPU 的架构和主频信息;
MEMORY: 表示发生内核崩溃的系统的内存大小;
PANIC: 表示内核崩溃的类型; 这里可能有 SysRq(即通过系统请求造
成的内核崩溃,如上面测试用的命令即是), Oops(表示内核
发生了不可预期的或不正确的行为,这时会杀死相应的进程,
内核可能恢复正常,也可能处于一种不确定的状态,并进而导
致内核的 Panic), 以及 Panic( 内核崩溃,即发生了严重且不可
修复的错误, 如发生了非法的地址访问, 强制加载或卸载内核
模块,以及硬件错误等等)。
PID: 表示导致内核崩溃的进程号;
COMMAND: 表示导致内核崩溃的进程名称
TASK: 表示导致内核崩溃的进程访问的内存地址;
CPU: 表示导致内核崩溃的进程占用的 CPU 数目;
STATE: 表示导致内核崩溃的进程的运行状态。
以上信息可用于初步分析内核崩溃的原因,内核态有三种出错情况,分别是 bug, oops
和 panic。 bug 属于轻微错误, oops 代表某一用户进程出现错误,需要杀死用户进程。
这时如果用户进程占用了某些信号锁,所以这些信号锁将永远不会得到释放,这会导致
系统潜在的不稳定性。 panic 是严重错误,代表整个系统崩溃。 深入的分析需要使用更
多的命令进行追踪和查找.
Crash 常用的命令有如下几个:
help #查看命令的帮助信息, 也可用 man 命令
h #查看历史命令,相当于 shell 下的 history
log #该命令用于打印出内存的日志信息
bt #该命令用于获取当前线程的调用堆栈
foreach bt #该命令用于获取所有线程的调用堆栈
ps #该命令用于查看内核崩溃时的进程信息
vm #该命令用于查看当前的内核上下文的虚拟内存信息
files #该命令用于查看当前的内核上下文中打开的文件
exit or q #退出 Crash
更详细的命令介绍可以查看官方介绍:http://people.redhat.com/anderson/help.html
crash经常发生在应用负载比较大的系统上,特别是大数据集群设备,接下来的会直接附上实际案例。
转载于:https://blog.51cto.com/kk876435928/2054256