数据库日志
cat dm_DMSERVER_202011.log | grep “ERROR” >1.log
cat dm_DMSERVER_202011.log | grep “FATAL” >2.log
数据库守护集群日志
dm_watcher_日期.log
共享存储集群日志检查
多出了 CSS 日志 dm_CSS节点名_日期.log
和 ASM 日志需要检查dm_ASM节点名_日期.log
连接数
SF_GET_PARA_VALUE (scope int, paraname varchar(256))
SP_SET_PARA_VALUE(1,‘MAX_SESSIONS’,1500);
IN FILE参数
select SF_GET_PARA_VALUE(2,‘MAX_SESSIONS’);
select para_name,para_value,SESS_VALUE,FILE_VALUE,"V
D
M
I
N
I
"
.
P
A
R
A
T
Y
P
E
f
r
o
m
v
DM_INI".PARA_TYPE from v
DMINI".PARATYPEfromvdm_ini where para_name=‘MAX_SESSIONS’;
ALTER SESSION 语法修改动态会话级参数(即 TYPE 为 SESSION 的参数)
ALTER SYSTEM SET ‘SORT_BUF_SIZE’ =200 DEFERRED MEMORY;
从ini 文件中取值:
SQL> select SF_GET_PARA_VALUE(1,‘MTAB_MEM_SIZE’);
从内存中取值:
SQL> select para_name,para_value from v$dm_ini where para_name=‘MTAB_MEM_SIZE’;
通过函数修改
1表示从dm.ini文件中读取;2表示从内存中读取;
1表示 dm.ini 文件和内存参数都修改,不需要重启服务器;2 表示只修改 dm.ini 文件,服务器重启后生效。
1SF_GET_PARA_VALUE 函数 SP_SET_PARA_VALUE 函数
返回 dm.ini 文件中非浮点和字符串类型的参数值
SF_GET_PARA_VALUE (scope int, paraname varchar(256))
scope: 取值为 1、2 。 1 表示从 dm.ini 文件中读取;2 表示从内存中读取;
1 PARA_NAME VARCHAR (128) 参数名称
2 PARA_VALUE VARCHAR (256) 系统参数值
3 MIN_VALUE VARCHAR (256) 最小值
4 MAX_VALUE VARCHAR (256) 最大值
5 MPP_CHK CHAR(1) 是否检查 MPP 节点间参数一致性。Y 是,N 否
6 SESS_VALUE VARCHAR(256) 会话参数值
7 FILE_VALUE VARCHAR(256) INI 文件中参数值
8 DESCRIPTION VARCHAR(256) 参数描述
DMRDC
dmrdc spfile=xxxx
gdb
利用Coredump文件对故障进行分析:因为达梦数据进程dmserver在故障出现后会将相关错误记录在【安装路径/bin】下,文件名为:****.core,一般为数字格式。使用gdb读取coredump的命令行读取这些.core::
[root@ora71 bin]# gdb dmserver core.25190
记录当前崩溃线程堆栈:
(gdb) bt
#0 0x00000000007e36a3 in nexp_gen_invocation ()
#1 0x00000000007e764f in nexp_gen_inv_args ()
(gdb)
记录当前崩溃线程号:
(gdb) info threads
前面有*为当前线程,LWP后面为线程号,如上图为2839。
对应的SQL语句(从dmrdc的结果中找对应的2839线程号,!#%&*^$@[线程号]):
!#%&*^$@[2839]:SELECT 1;^
单独执行SQL语句是否可重现问题:
四、Coredump文件所有线程堆栈信息及所有的SQL语句
(gdb)set logging file /opt/dmdbms/log/stack.log
(gdb)set logging on
(gdb)thread apply all bt
(gdb)set logging off
记录stack.log内容:
记录dmrdc结果:
./dmrdc sfile=core.xxx dfile=result.txt
ps -ef|grep dmserver
dmdba 25190 1 0 01:51 ? 00:02:23 /home/dmdba/dmdbms/bin/dmserver /dm8/data/DAMENG/dm.ini -noconsole
[root@ora71 ~]# cd /home/dmdba/dmdbms/bin/
[root@ora71 bin]# gdb dmserver
(gdb) attach 25190
(gdb) detach
(gdb) quit
[root@ora71 bin]# gdb dmserver core.25190
实例故障
DM 实例故障,即数据库进程 dmserver 出现异常,表现为异常中止,进程存在但无响应或者无法登录的状态,出现此类问题都属于比较严重的故障,一般情况下我们需要尽可能的收集到所需要的信息进行故障分析,这里我们将把故障分为两类,来讲下出现类似场景时需要收集哪些有价值内容供后续处理。
先简单说明下我们可能会用到的工具和一些术语:
core 文件:程序异常时操作系统保留的完整进程的内存镜像文件。
gdb:用于调试执行程序或者 core 文件的工具。
堆栈:程序执行中的运行情况,详细包含了运行时函数调用数据以及数据相关信息。
dmrdc:DM 数据库提供的自带对 core 文件进行简单分析的小工具,以 core 文件作为输入参数,dmrdc 可以从 core 文件中读出所有异常时活动会话上的 SQL 语句信息。
异常中止类问题
Dmserver 进程运行过程中异常中止,进程在进程管理器中无法找到,一般可能由以下几种情况引起。
数据库主动自杀 (halt)
数据库实例在运行过程中会实时进行一些检查,比如授权过期信息、文件完整性信息、内存是否污染信息、数据页校验信息等,如果出现一些比较严重的问题被数据库自查到,数据库自身会选择自杀并给出提示信息,来防止更严重的错误产生,这种情况下导致的进程中止,我们需要检查数据库运行日志,搜索 halt 相关的内容,在 halt 内容附近会记录 halt 的详细原因,比如授权过期、文件不完整、内存被污染等,根据相关的信息进行对应的处理,一般情况下可以将数据库恢复至正常运行状态,由于 halt 的内容由非常多种,在此不逐一列举。
虽然有一些 halt 可以通过简单处理后(比如授权过期)立即恢复服务,但有一些也是我们需要非常留意的,特别是内存校验失败、数据文件校验失败相关的信息,这种一般也是一些语句在操作时出现内存泄露或者写溢出等导致,我们需要结合数据库异常时生成的 core 文件进行分析,才能最终确认问题的症结。
这种情况下,我们可以通过以下方法解决:
需要数据库的运行日志来确认 halt 原因。
需要 core 文件的堆栈来确认发生异常时相关线程的函数调用顺序。
需要 dmrdc 对 core 文件分析的结果,如果异常发生在 SQL 执行线程上,dmrdc 工具有很大的概率将导致异常的语句挖掘出来。
数据库自身缺陷导致程序异常
这类问题一般比较严重,在数据库运行日志中大多数时候没有任何异常苗头就突然中断,数据库进程同时也会中止,仅在操作系统日志中会留下痕迹,如果数据库进程发生异常中止,并且在数据库运行日志中没有 halt 相关的信息,我们需要检查一下操作系统日志(一般是在 /var/log/message* 中,需要 root 权限查看)中是否有 dm 的相关信息,可以通过关键字 dm 搜索,或者通过数据库运行日志来确认异常前的数据库实例进程号来进行搜索,看操作系统日志中有没有记录相关的信息,如果是数据库自身问题导致的异常,一般会在操作系统日志的相关记录中有 **segfault 、page fault `**之类的信息。
这种情况下,我们可以通过以下方法解决:
需要操作系统日志的相关片段、数据库运行日志、gdb 查看 core 文件的堆栈信息、dmrdc 读取 core 文件的输出信息等。
通过 gdb 查看到的异常线程 LWP 号(gdb 打开 core 文件后输入 info thread 查看到的最后一个 LWP)可以在 dmrdc 的输出中找到对应的语句
需要确认一下语句是否为常用语句,如果不常使用,或者业务上能确认是新功能引入,可以暂时先通过关闭对应功能恢复服务,将收集的信息反馈给服务中心进行处理。
操作系统将数据库进程杀死
一般有以下几种情况可能导致操作系统主动杀死数据库进程:
最常见的是 OOM KILL,这种情况在操作系统运行日志中可以明显的搜索到 oom 相关信息,并且 OOM 导致的进程异常是没有 core 文件的,因为 OOM 后系统是发送的 SIGTERML 对数据库进程进行杀死,这种情况案发生后,一般需要对数据的内存相关参数以及操作系统 OOM 评分优先级等设置进行调整。
另外一种就是杀毒软件或者安全软件,对数据库的某些线程进行污染,导致线程异常,进而导致数据库进程异常,这种异常在操作系统运行中表现为可以搜索到 DM 相关的信息中包含 tained 等内容,如果出现这种情况,需要检查一下环境中是否存在安全软件对 DM 的进程进行监控等动作。
连接异常类问题
大多数情况下,连接异常类问题都是由于配置不正确导致。
具体的表现:在任务管理器中查看 dmserver 进程能够看到正常的 CPU 活动信息,查看磁盘网络等活动也存在正常的波动,但是新建连接连接数据库会提示网络通讯异常。
最常见的原因:
dm.ini 中限制了最大连接数(相关参数 MAX_SESSIONS),数据库连接达到该值后会拒绝创建新连接,在数据库运行日志中会发现 reach max session limit 相关日志。
由于操作系统的用户资源限制引起,我们通过命令 cat /proc/dmserver 的 pid/limits 可以查看到当前数据库进程的一些资源限制,我们主要关注的是 Open files 这个限制,由于在 DM 中每一个会话都是一个线程,一个线程在 linux 中需要一个独立的文件句柄去控制,如果该项限制太小,会导致创建线程失败,从而在外部显示为连接数据库失败,这种情况一般在数据库运行日志中会有 create thread failed 相关信息,并且检查进程 limits 会发现 Open files 限制的较小,通过 ls -l /proc/dmserver 的 pid/fd|grep -c 命令,查看数据库已经打开的句柄以及等于或者超过 limits 值,由于这些 limits 是在进程启动时生效的,不能动态修改,如果已经出现了这种现象,只能修改相关的配置(ulimit -n 65535等命令),并且重启数据库进程。
少数情况下,连接异常问题是由于数据库自身的缺陷引起,如果出现连接异常,检查数据库配置以及操作系统配置没有发现异常,并且连接数据库时长期不成功也不返回报错,这种情况大概率时由于数据库自身的原因导致客户端连接过程中发生资源等待或者死锁,导致登录消息一直陷入在资源/临界区等待状态,如果有类似的现象,在可能的情况下,我们可以使用gdb/pstack工具对数据库进行一个堆栈快照供服务中心新进分析,从堆栈快照中来分析相关登录在等待哪些临界区或者资源,并确认是否是数据库 BUG 导致。