Linux环境下,当达梦数据库异常退出时,会产生一个core文件,又称为 core dump 文件,该文件记录了达梦数据库运行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等,达梦数据库工作当前状态存储会生成的一个文件,通过工具分析这个文件,我们可以定位到达梦数据库异常退出时,对应的堆栈调用等信息,帮助开发、运维人员定位问题并及时提供解决问题方法。
一.达梦core环境配置
1.配置开启core文件
ulimit -a
--查看core file size ,为0,说明未配置开启core
vi /etc/profile
增加:ulimit -c unlimited
source /etc/profile
ulimit -a,可以查看core file size 已为unlimited,则core文件为已开启
- 配置core路径
查看core路径:
cat /proc/sys/kernel/core_pattern
|/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e %P %I %h
|/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e %P %I %h这样的字符串,其中“%s”表示core文件名称,“%p”表示进程ID,“%u”表示用户ID,“%g”表示组ID,“%t”表示时间戳,“%P”表示父进程ID,“%I”表示线程ID,“%h”表示主机名
修改coredump目录,指定生成目录为/coredump,添加pid作为扩展名,生成的core文件名称为cmd.core.pid,在/etc/sysctl.conf中,增加配置:
kernel.core_uses_pid = 1
kernel.core_pattern=/coredump/%e.core.%p
当core产生时,会生成程序名+core+PID号,如下:
二.GDB调试达梦数据库CORE
线上通过GDB调试core, 获取导致数据库异常的信息,便于发现异常原因包括但不限于异常 sql、必要的文件丢失或损毁等。
GDB加载达梦core文件
命令格式:gdb dmprogam core_name
如:
Ps -ef|grep ini查看程序位置,在/coredump目录下,gdb加载core,例如下:
gdb /dm/dmdbms/bin/dmserver dm_sql_thd.core.93871
定位达梦数据库异常位置
bt查看堆栈
GDB加载了core文件,我们可以使用bt命令来查看异常位置,该命令会显示函数调用堆栈跟踪信息,从而定位到导致数据库异常的代码行。
如:
Info threads查看所有线程
有时候,需要查看所有线程,才能排查问题,Info threads查看所有线程
Info threads
打印所有线程堆栈
set logging file <文件名> #设置输出的文件名称
set logging on #开始将调试信息将输出到指定文件
thread apply all bt #打印所有线程栈信息
set logging off #关闭到指定文件的输出
quit #结束gdb调试
如下,未指定目录情况下,会默认生成gdb.txt:
切换线程堆栈查看堆栈
Thread 线程号,如:
查看堆栈内信息
查看指定栈层f n
f n定位到导致程序异常的代码行
查看栈层详细信息info frame
Info frame 或i f命令,查看堆栈寄存器信息
查看栈层函数参数及值info args
查看函数中所有局部变量及值info locals
查看参数结构体ptype
f n 进入堆栈层,可以查看参数的结构体,如查看pln的结构
查看session中的SQL语句 p &p
代表查看表达式的值,&p代表变量p的地址,f n进入到包含stmt参数的栈层,p stmt->sess>sqls可以查看当前的SQL语句
查看当前寄存器信息info registers
使用info registers命令可以查看CPU寄存器的值
显示内存地址中的汇编指令
查看一段内存地址中存储的汇编指令,可以使用GDB X命令的汇编格式 x/ni,如打印函数中,n个汇编命令
三.达梦数据库core分析思路
对于达梦数据库服务端进程 core dump 来说,分以下两种情况:
(1)服务端主动 core
这一类 core dump 问题相对来说比较好定位问题,因为服务端主动 core 表示程序因某种资源不够或已知原因而发生的“自杀”行为,一般在达梦数据库运行日志或 core 堆栈中会出现 dm_sys_halt 的信息,这种情况下通过堆栈和日志信息便可以确定发生问题的原因。
(2)因未知异常原因导致的 core
这一类 core dump 相对来说更加隐晦一些,因为这一类是服务端程序被迫发生的,例如内存访问越界、非法指针、堆栈溢出等问题,主要表现为达梦数据库运行日志检查点突然中断,没有任何信息,但这一类问题的原因往往是由某个 sql 语句引发的,只需要找到对应的 sql 语句即可。