kdump和crash的配置方法與內核故障原因分析(一)

 最近數據庫服務器備機升級網卡驅動版本以及大數據有個別設備直接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經常發生在應用負載比較大的系統上,特別是大數據集羣設備,接下來的會直接附上實際案例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章