目录
一、SQL类故障
(一)SQL长时间等待问题
数据库若出现 SQL 长时间等待的情况,可以从以下几个方向进行排查:
- 执行过程中某些对象或资源发生等待,导致执行语句长时间等待不能返回。
- 所执行语句本身存在性能问题。
- 其他异常情况。
1.对象或资源发生等待问题
跟如果存在长时间没有返回结果的语句,首先通过 V$SESSIONS 确认语句处于活动状态,语句如下:
SELECT * FROM v$sessions WHERE state='ACTIVE'
AND dbms_lob.substr(sf_get_session_sql(sess_id)) LIKE '%语句片段%'
明确事务等待导致语句没有正常执行结束,语句如下:
SELECT * FROM v$trxwait WHERE id = 上述语句得到结果的 TRX_ID。
V$TRXWAIT查询得到结果的WAIT_FOR_ID字段标记的事务即为当前语句正在等待的事务。通过 SELECT * FROM v$sessions WHERE trx_id =查询到的WAIT_FOR_ID; 可以得到当前事务所在等待会话的一些信息,一般来说,因为某些会话或者客户端忘记进行提交或者回滚操作,后续一直空闲,导致其他的事务由于跟该事务存在一些事务上的依赖关系发生等待。针对这种情况,需要在确认安全的情况下针对这个阻塞源头的会话进行操作,可以通过关闭客户端、关闭会话、发送提交或者回滚命令等方式结束等待的会话。
当V$TRXWAIT查询不到结果时,可以通过查询 SELECT * FROM v$lock WHERE blocked = 1; 来进行确认,在查询结果中可以对相关锁对象的持有事务来查询来确认阻塞来源。
注意
一般情况下 DDL 导致的等待会有一个显示的等待时间,由 dm.ini 配置文件中的参数 DDL_WAIT_TIME 来进行控制,默认为 10,也就是说如果等待 10 秒钟后,阻塞源头的 DDL 还没有执行完释放资源,会抛出锁超时错误。可以适当调大等待时间再次运行查看是否还会抛出锁超时错误。
2.性能问题
首先确认 sql 是否存在事务等待,如果不存在事务等待需要确认 sql 本身是否存在性能问题。
确认语句处于活动状态,语句如下:
SELECT * FROM v$sessions WHERE state='ACTIVE'
AND dbms_lob.substr(sf_get_session_sql(sess_id)) LIKE '%语句片段%'
查询等待事务:
SELECT * FROM v$trxwait WHERE id = 上述语句得到结果的 TRX_ID
若查询不到结果,说明该语句没有发生事务性等待。如果发现语句活动,且没有事务性等待,则大概率是该语句自身执行存在效率问题,需要对执行计划进行调整。
3.其他异常情况问题
若对象或资源未发生等待,且SQL语句的执行性能正常,则可参考以下排查思路:
- 临时表空间大小限制。在dm.ini配置文件中对TEMP表空间大小进行了限制,查询中存在/SORT/HASH JOIN/HAGR等操作使用临时表空间,在临时表空间没有被其他会话释放时发生等待。
- 刷新REDO日志语句出现等待。主备、读写分离等环境运行过程中,由于备机自身或者配置相关的原因(备机IO出现异常、主备网络异常、数据延迟达到配置的主备最大延迟)等,导致主机上运行一些需要刷REDO日志的语句时发生等待。
- 相关表出现大批量修改操作。大表发生大批量删除数据后,由于这些数据都只是被标记删除,在一定事件后会由回收站进行统一的清理操作,清理过程中需要对数据页进行修改,而涉及的数据页又非常多,导致的执行速度缓慢。
(二)SQL执行过程中数据库进程异常问题
SQL 执行过程中数据库进程异常一般分为以下几类:
- 运行过程中数据库发生 Halt
- 运行过程中数据库段错误 Segfault
- 运行过程中发生 PAGE FAULT
- 运行过程中发生线程污染 TAINED
- 运行过程中发生 OOM 错误
对于Segfault,PAGE FAULT,TAINED与OOM错误,在数据库运行日志中一般不会发现明显的信息,这些错误可以通过查询操作系统日志,一般是/var/log/messages*,然后搜索异常前的dmserver的进程号或者搜索DM相关的信息,根据查询到的不同的信息类型进行不同的处理。
1.Halt错误
对于Halt类型错误,可以通过查看数据库的运行日志,搜索“Halt”关键字,如果发现存在Halt字样的日志内容,会在Halt之前有具体的Halt原因说明,这是数据自己保证数据安全的一种方式,当检测到一些严重异常时,采取自杀(自行停止)的方式来保全数据,防止产生更严重的问题。
2.Segfault 错误
对于Segfault类型错误,可以通过查看操作系统日志,需要说明的是,Segfault类型错误一般是由数据库Halt时通过主动进行除0操作引发的异常时,如果不是Halt,则可能是由于某些语句引起。可以参考以下步骤进行处理:
- 通过dmrdc工具对异常生成的core文件进行信息读取,读取后会得到一个数据文件,输出文件的格式为[线程号] SQL语句内容。
- 通过gdb工具打开异常时生成的core文件进行检查。
- 通过info thread命令,找到出现异常的线程,线程对应的LWP后跟的数字即为异常线程号。
- 通过GDB找到的异常线程号去dmrdc的输出文件中进行搜索,得到的语句就是导致异常的语句,如果语句可以稳定重现,可以将gdb该core文件的bt输出内容、相关语句发送到相关技术服务人员进行确认。
3.Page fault 错误
对于Page fault类型错误,可以通过查看操作系统日志,一般PAGE FUALT后会跟有具体的错误码,即code: xx,在LINUX内核中定义了这些报错对应的内容。
如果code是0,一般是由于数据库运行中没有办法申请到需要使用的内存导致,这种时候需要考虑在dm.ini中修改相关配置,调整数据库的内存使用量。其他几种code或者是 code的组合(比如6 = 4 + 2表示存在两种错误),基本是发生内存读写越界引起。
4.Tained 错误
对于Tained类型错误,可以通过查看操作系统日志,如果操作系统日志中出现了DM相关线程tained相关的信息,一般是由于第三方软件(主要是杀毒软件或者安全软件),对DM的相关线程进行污染,导致数据库的一些线程被异常中止,不同类型的线程被中止可能导致不同的结果,而且是不可预期的,这种情况下需要及时调整系统环境,让相关软件尽量不影响数据库进程。
5.OOM错误
这种也是比较常见的错误,OOM作为操作系统本身对于自己的一种保护机制,对占用大量内存的进程,如果满足一定条件,就会被操作系统中止,腾出空余内存,如果频繁发生数据库进程被OOM kill,则需要调整数据库内存相关参数和操作系统内存相关参数等,防止数据库进程被频繁OOM。
(三)SQL结果集异常问题
首先需要找到结果集异常的SQL语句,可以通过LOGCOMMIT日志、V$SQL_HISTORY视图等来查找。
一般情况下,结果集异常是由于优化器对查询语句的错误改写或者优化导致,在提取SQL时尽量保证提取到的语句和实际执行的语句严格一致,要求绑定参数相同、数据库参数一致,这样可以在进行验证时的语句执行计划和出错时一致。
在计划一致的情况下,如果可以重现查询结果集异常的情况,可以尝试对异常的查询语句进行裁剪,也可以参照当前计划,有目的修改通过SQL语句摘除计划中的某些操作符,一步步得到结果集出错的最精简语句。
还可以通过修改参数/HINT/,改写语句等方式,调整问题操作符为等价的其他操作符,查看是否可以规避问题,如果不能通过等价修改的方式绕过该问题,可以及时整理重现用例将问题反馈给有关部门。
另外一些特殊情况的结果集异常可能是因为某些信息没有及时更新或者错误使用导致,包括但不限于:
- 查询涉及到全文索引没有更新。
- 查询涉及到的物化视图没有更新。
- 错误的使用确定性函数标记了不确定函数。
- 非一致读备机查询数据存在延迟。
二、实例类故障
(一)数据库连接异常处理
1.数据库连接异常排查思路
数据库无法登录原因有很多。当出现该类问题时,重要的是先分析原因,再根据原因进行处理。当数据库出现连接异常时,可通过下图所示思路进行排查:
(1)检查网络情况
确定服务器端防火墙关闭的情况下,可以使用ping及telnet工具测试客户端到数据库服务器的IP地址及端口是否能够正常通讯。例如:ping 192.168.1.1, 或telnet 192.168.1.1 5236如果不能正常通信说明网络或端口异常,需要排查网络。如果能够正常通信,需进行下一步排查。
(2)检查数据库状态
如果网络正常,登录数据库服务器检查数据库的状态。执行 ps -ef|grep dmserver 命令判断数据库服务进程是否存在。
(3)检查数据库运行日志
打开数据库日志观察数据库是正常关闭,还是有[ERROR]或者[FATAL]标签,对情况进行具体分析
(4)登录数据库
进入数据库程序安装路径中执行 ./disql SYSDBA/SYSDBA@192.168.1.1:5326 数据库用户、密码、IP 和端口号以实际现场为准。如果正常登录说明数据库正常,如果登录失败可以参考步骤 3。
(5)查看 core 文件
打印堆栈联系技术人员排查。
(二)异常中止类问题
dmserver 进程运行过程中异常中止,进程在进程管理器中无法找到,一般可能由以下几种情况引起。
- 数据库主动停库导致访问异常
- 操作系统将数据库进程终止导致访问异常
1.数据库主动停库导致访问异常
数据库实例在运行过程中会实时进行一些检查,比如授权过期信息、文件完整性信息、内存是否污染信息、数据页校验信息等,如果出现一些比较严重的问题被数据库自查到,数据库自身会选择主动停库并给出提示信息,来防止更严重的错误产生。这种情况下导致的进程中止,需要检查数据库运行日志,搜索Halt相关的内容,在Halt内容附近会记录Halt 的详细原因,比如授权过期、文件不完整、内存被污染等,根据相关的信息进行对应的处理,一般情况下可以将数据库恢复至正常运行状态,由于Halt的内容有非常多种,在此不逐一列举。
虽然有一些Halt可以通过简单处理后(比如授权过期),可以立即恢复服务,但有一些特殊情况需要额外留意,例如内存校验失败、数据文件校验失败相关的信息,这种情况一般是数据库在出现内存泄漏或者写溢出等导致,需要结合数据库异常时生成的core文件进行分析,才能最终确认问题的症结。
当数据库主动停库导致访问异常时,可以通过以下思路解决:
- 查看数据库的运行日志来确认主动停库的原因。
- 查看core文件的堆栈来确认发生异常时相关线程的函数调用顺序。
- 利用dmrdc工具分析core文件,如果异常发生在SQL执行线程上,dmrdc工具有很大的概率可将导致异常的语句挖掘出来。
2.操作系统将数据库进程终止导致访问异常
一般有以下几种情况可能导致操作系统主动终止数据库进程:
情况一:数据库被 OOM KILL
此为操作系统主动终止数据库进程最常见的情况。数据库的正常运行依赖于能够正常申请操作系统的相关资源,例如当内存不够或内存使用过多时可能发生OOM异常,当文件打开数设置的过小可能造成用户无法正常登录数据库,在进行项目实际环境部署时,应该检查这些操作系统资源并进行合理设置。
data seg size 建议设置为1048576以上或 unlimited,若此参数过小将导致数据库启动失败。用vim打开配置文件vi /etc/security/limits.conf在下面加两行。
dmdba soft data unlimited
dmdba hard data unlimited
file size建议设置unlimited (无限制)。若此参数设置过小,则会导致数据库安装或初始化失败,file size需要在/etc/security/limits.conf文件中配置。
dmdba soft fsize unlimited
dmdba hard fsize unlimited
open files建议设置为65536以上或unlimited。用vim打开配置文件vi /etc/security/limits.conf 在下面加两行。
dmdba soft nolife 65536
dmdba hard nolife 65536
virtual memory建议设置为 1048576 以上或 unlimited,此参数过小将导致数据库启动失败。
max user processes最大线程数这个参数建议修改为10240。用vim打开配置文件vi /etc/security/limits.conf在下面加两行。
dmdba soft nproc 10240
dmdba hard nproc 10240
或者在dmserver的启动脚本中加入ulimit -u 10240。
nice设置优先级,值越小表示进程“优先级”越高。用vim打开配置文件vi /etc/security/limits.conf在下面加两行。
dmdba soft nice 0
dmdba hard nice 0
地址空间限制设置为ulimit。用vim打开配置文件vi /etc/security/limits.conf在下面加两行。
dmdba soft as unlimited
dmdba hard as unlimited
内核文件大小建议设置为ulimit。用vim打开配置文件vi /etc/security/limits.conf在下面加两行。
dmdba soft core unlimited
dmdba hard core unlimited
注意:
通过systemctl或者systemd service方式设定随机自启动的数据库服务, 其能打开的最大文件描述符、proc数量等不受limits.conf控制,需要修改/etc/systemd/system.conf文件,增加类似DefaultLimitNOFILE=65535重启服务器生效,如下:
DefaultLimitFSIZE=unlimited
DefaultLimitDATA=unlimited
DefaultLimitCORE=unlimited
DefaultLimitNOFILE=65536
DefaultLimitAS=unlimited
DefaultLimitNPROC=10240
DefaultLimitNICE=0
在数据库运行之后,可执行cat /proc/pid号/limits命令,检查实际资源限制是否生效。
情况二:杀毒软件或者安全软件导致数据库进程异常
系统环境中若存在杀毒软件或者安全软件,可能对数据库的某些线程产生污染,导致线程异常,进而导致数据库进程异常,这种异常在操作系统运行中表现为可以搜索到DM相关的信息中包含Tained等内容,如果出现这种情况,需要检查环境中是否存在安全软件对DM的进程进行监控等动作。
如存在其他异常问题,可通过查询操作系统/var/log/messages*等日志搜索dmserver进程,查看异常情况。
3.连接异常类问题
数据库连接异常问题具体表现:在任务管理器中查看 dmserver 进程能够看到正常的 CPU 活动信息,查看磁盘网络等活动也存在正常的波动,但是新建连接连接数据库会提示网络通讯异常。大多数情况下,连接异常类问题是由于相关配置不正确导致。建议排查连接的 ip 及端口是否正常通信、应用的 url 配置是否正确、应用使用的达梦数据库驱动是否和数据库服务器端的驱动版本一致等。
(1)连接数满
达梦数据库通过配置系统参数MAX_SESSIONS以及设置单个数据库用户的连接数上限来管控数据库连接数。当客户端向数据库发起连接申请时,首先会占用系统的总会话数,随后再进行用户名密码的验证,并验证是否达到单个用户的连接数上限。一般情况下,当数据库连接数达到MAX_SESSIONS后,新建数据库连接会出现【超过最大连接限制】报错。此时仅能再允许一个系统管理员SYSDBA用户的登陆,成功建立最后一个SYSDBA连接后,数据库连接会达到MAX_SESSIONS+1。如果此时再新建连接,会返回【网络通信异常】报错。
在遇到数据库连接数达到上限的问题时,为了快速恢复系统,可以参考如下思路进行恢复:
- 从数据库中查找连接数过多的应用,停止应用程序。
- 直接停止不重要程序,快速释放部分连接数,后续可以登录上数据库后,可以通过系统函数踢出数据库空连接或无实际业务操作仅用于探测数据库连接的[例如 select 1]会话或者限制某些IP连接数据库。
- 若最终仍无法登录数据库,可选择重启数据库来恢复系统。
- 查看数据库用户资源限制是否设置最大空闲时间。
(2)句柄数满
达梦数据库通过配置系统参数MAX_SESSION_STATEMENT来管控数据库单个会话上允许同时打开的语句句柄最大数。一般情况下,当单个会话上句柄数达到MAX_SESSION_STATEMENT设置后,会出现【语句句柄个数超上限或系统内存不足】报错。
在遇到该问题时,为了快速恢复系统,可以参考如下思路进行恢复:
- 可以通过调大dm.ini文件中的MAX_SESSION_STATEMENT参数暂时解决问题。
- 可以通过语句查询各个会话的句柄数量。
select
sql_text ,
state ,
n_stmt "句柄的容量" ,
n_used_stmt as "使用的句柄数",
curr_sch ,
user_name ,
trx_id ,
create_time ,
clnt_type ,
clnt_ip ,
run_status
from
v$sessions;
该问题一般都是由应用不规范开发导致,若要从根本上解决问题,建议将相关问题反馈给应用开发人员,对代码进行修改、规范,保证会话用完后能够及时关闭。
(3)全局hash join满
全局hash join满会出现以下报错。
dm.jdbc.driver.DMException:超出全局hash join空间,适当增加HJ_BU_GLOBAL_SIZE
at dm.jdbc.driver.DBError.throwException(DBError.java:657)
at dm.jdbc.a.b.p.H(MSG.java:582)
at dm.jdbc.a.b.p.E(MSG.java:542)
......
出现该问题一般是由于系统中同一时间有大量工作线程在做 hash join 操作,而全局排序区由参数HJ_BUF_GLOBAL_SIZE来控制,所以有以下两种方法进行处理:
方法一:临时处理方法。修改HJ_BUF_GLOBAL_SIZE参数,该参数是动态参数,可以通过以下命令修改alter SYSTEM set 'HJ_BUF_GLOBAL_SIZE'=3000; 参数具体设置按照内存大小来确定。
方法二:推荐方法。找到报错的SQL语句并进行优化,可将hash join优化为nest loop。
(4)客户端与服务端版本不匹配问题
当客户端工具与数据库服务器端版本不匹配时,使用客户端工具连接数据库可能导致如下异常:
- 管理工具连接达梦数据库报错 “argument cannot be null”。
- 管理工具登录后左侧导航栏不显示出来。
- 管理工具登录后报系统错误。
当出现上述情况时,更换使用与服务端版本相同的客户端版本即可正常进行相关操作。
(5)中间件的连接池配置异常
当启动应用并运行一段时间,数据库的实际连接数远低于参数允许的最大会话连接数,但应用却报“网络通信异常”或者“数据库连接关闭”。
- 建议从以下方面排查:
- 排查中间件的连接池配置信息。
- 排查中间件的连接池中的泄漏超时时间。
(6)连接已重置
应用抛出“连接已重置”的异常。
建议从以下几个方面尝试排查解决:
- 使用数据库服务器上$DM_HOME/drivers目录下的驱动包。
- 查看会话数是否不够。
select para_name,para_value from v$parameter where name='MAX_SESSIONS';
- 检查是否用户设置了最大空闲时间参数,导致超时断开。
select b.username账号,b.password_versions密码策略,a.sess_per_user同时拥有的会话数,a.conn_idle_time会话访问服务器的时间上限from sysusers a,dba_users b where a.id=b.user_id;
- 长时间执行ping命令(从应用服务器到数据库服务器),查看是否为网络波动导致此报错。
- 检查应用的连接池设置,是否设置了断开后自动连接。
- 以上都检查后,可以开启驱动日志进一步分析。
(三)数据守护集群故障处理
1.数据不同步
对于主备数据不同步的问题,需要排查以下问题:
- 查看数据库状态是否存在多个主库,是否出现脑裂;
- 通过 dmmonitor 监视器和 dmwatcher 日志,查看主备集群状态,是否分裂;
- 查看 dmwatcher 进程是否正常启动;
- 查看备机 dmserver 实例是否正常进入 open 状态;
- 通过 ping、telnet 操作系统命令来查看 MAL 系统的网络端口是否通畅;
- 通过 dmrachk 工具查看主库归档是否连续;
- 借助监视器的 check recover 命令查看备库不满足 recovery 的原因;
- 查看数据库授权是否支持集群部署选项;
- 查看归档保存路径是否有权限写入归档文件,查看磁盘空间是否充足。
2.主机的故障处理与恢复
故障自动切换模式下,确认监视器检测到主库故障后,根据收到的主备库LSN、归档状态、MAL链路状态等信息,确定一个接管备库,并将其切换为主库。
手动切换模式下,可以通过监视器的takeover命令,将备库切换为主库,继续对外提供服务。具体操作如下:
使用 SYSDBA 用户登录监视器。
./dmmonitor /home/dmdba/dm/dmdbms/bin/dmmonitor.ini
login
用户名:SYSDBA
密码:SYSDBA
使用takeover集群组名.实例名 命令接管故障主库。
执行show命令查看确认。
如果执行takeover命令不成功,主库也无法马上恢复,为了及时恢复数据库服务,DM提供了takeover force命令,强制将备库切换为主库。但需要由用户确认主库故障前,主库与接管备库的数据是一致的(主库到备库的归档是Valid状态),避免引发守护进程组分裂。
takeover force集群组名.实例名
注意
执行Takeover Force有可能引发组分裂,而Takeover命令是在确保不会产生组分裂情况下才允许执行。
3.集群组分裂与脑裂
(1)集群组分裂
同一守护进程组中,不同数据库实例的数据出现不一致,并且无法通过重演Redo日志重新同步数据的情况称为组分裂。引发组分裂的原因主要有以下两种:
即时归档中,主库在将Redo日志写入本地联机Redo日志文件之后,发送Redo日志到备库之前出现故障,导致主备库数据不一致,为了继续提供服务,执行备库强制接管。此时,当故障主库重启后,就会引发组分裂。
故障备库重新完成数据同步之前,主库硬件故障,并且长时间无法恢复,在用户接受丢失部分数据情况下,为了尽快恢复数据库服务,执行备库强制接管,将备库切换为主库。此时,如果故障主库重启,也会造成组分裂。
借助监视器的show命令或者tip命令可以查看守护系统中是否发生实例的分裂,对于已发生的分裂,可以借助以下方法找出分裂产生的原因:
- 查看分裂实例的服务器的 log 日志,查找带有 [!!!] 和 [!!!] 标签的 log 信息,log 信息格式形如 [!!! LOG_INFO !!!]。该 log 信息中记录有实例分裂的详细原因。
- 根据服务器和监视器的 log 日志,找出历史操作信息,分析产生分裂的原因。
发生分裂后,用户需要选择适当的主库作为最新主库,并重建备库后重新加入集群。
具体重建数据守护步骤如下:(以一个库的数据为准,进行数据库备份)
- 备库重新初始化数据库实例(原数据文件存放目录,在阵列磁盘空间足够的情况下,进行重命名处理)。
./dminit ini_file=/home/dmdba/data/TEST/dm.ini path=/home/dmdba/data DB_NAME=TEST extent_size=16 page_size=32 case_sensitive=y log_size=2048
- 使用物理备份进行数据库还原。
scp-rp$2022_03_10备份集dmdba@IP:/home/dmdba/data/TEST/bak
--dmdba用户下启动dmrman
--校验备份文件
RMAN>CHECK BACKUPSET'/home/dmdba/data/TEST/bak/DB_TEST_FULL_2021_03_14_15_35_30';
./dmrman
>restore database '/home/dmdba/data/TEST/dm.ini' from backupset '/home/dmdba/data/TEST/bak/DB_TEST_INCRE_2021_03_14_15_38_28' with backupdir '/home/dmdba/data/TEST/bak/DB_TEST_FULL_2021_03_14_15_35_30';
>recover database '/home/dmdba/data/TEST/dm.ini' with archivedir '/home/dmdba/data/TEST/arch' until time '2021-03-14 17:18:00';
--进行数据库恢复,可以使用拷贝归档日志的方式,缩短主备恢复一致时间,
>recover database '/home/dmdba/data/TEST/dm.ini' update db_magic;
>exit
- 登录备库,修改备库状态。
SQL>SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 1);
SQL>alter database STANDBY;
SQL>SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 0);
- 重新配置备库的dm.ini、dmwatcher.ini和dmwatcher.ini文件,启动dmwatcher和 dmmonitor观察数据同步是否正常。
(2)集群脑裂
脑裂指同一个守护进程组中,同时出现两个或者多个活动主库,并且这些主库都接收用户请求,提供完整数据库服务。一旦发生脑裂, 将无法保证数据一致性,对数据安全造成严重后果。发生脑裂主要有两个原因:网络不稳定或错误的人工干预。
三、人为操作类故障
(一)文件误删或损坏
DM 数据库实例包含数据文件部分和执行文件部分:
- 数据文件是通过DM的实例初始化工具初始化的实例文件,包含数据文件(DBF文件)、配置文件(ini文件)、控制文件(ctl文件)以及一些其他必须的文件(dm_service.prikey) 等;
- 执行文件即通过DM的安装包安装后在目标机器上存在的可执行程序以及动态库。若此类文件在运行过程中被误删除,可能导致异常情况。
1.执行文件被误删除
在Windows环境下,执行文件在被引用过程中是无法被删除的,出现此类问题的情况比较少,但在Linux环境下,数据库进程存在的情况下,相关执行文件可以被删除,程序会继续运行,但是运行过程中的日志等文件在程序执行完后可能会丢失,此情况下,通过查询dmserver的进程pid,然后进入到/proc/pid/cwd路径下,仍然可以看到执行过程中依赖的相关文件,可以通过拷贝命令将相关文件拷贝存放,供后续使用。
2.控制文件误删除
控制文件,即dm.ctl文件,其中记录了数据库实例相关信息、数据版本信息和重做日志文件、数据文件路径属性等,如果被异常删除,表空间属性相关修改可能出现异常,如果不能正常修复,可能导致某些数据文件、REDO日志文件没有被数据库实例纳入到管理范围,引发其他的严重问题。
如果发现该文件被异常删除,需要及时对该文件进行恢复,DM数据库自身定期会对该文件进行备份,dm.ctl文件的备份路径可以在dm.ini中进行配置。
- 进入dm.ctl文件的备份目录。
- 在该目录下找到最接近故障时间的dm.ctl备份文件。
- 通过$DM_HOME/bin目录下的dmctlcvt工具将dm.ctl转换成可读的txt文件。
- 打开txt文件,通过数据库客户端进行查询vdatafile以及vrlogfile,以动态视图结果为准仔细检查各个文件是否可以和txt文件中的配置逐一对应,如果存在差异,手工对txt文件中的内容进行修改。
- 修改完成后,通过dmctlcvt工具将txt文件转换成ctl文件,移动到dm.ini中配置的ctl文件路径下,至此修复完成。
3.dm_service.prikey文件误删除
实例的RSA钥文件涉及数据库一些重要数据的加解密,误删除无法简单处理,需要联系原厂工程师进行支持。
DM在运行过程中会定期对这些比较重要的文件进行存在性检查,如果异常会在数据库运行日志中,巡检时需要留意。
4.REDO 日志文件误删除或损坏
REDO日志文件默认在数据库实例下,以实例名.log命名,该文件记录的是数据库运行过程中对数据文件修改的日志信息,并且相关的修改信息达到一定的条件才会实际被应用在数据文件上,如果误删除,首先在日志上没有被应用的日志信息涉及的数据将丢失,此外可能导致数据库无法正常启动。
当数据库redo日志文件误删除或损坏,数据库无法启动时,可以使用物理备份还原的方式,将数据库还原到指定的时间节点,由于归档文件中如实的记录了REDO日志的信息,所以REDO日志中涉及的数据可以通过备份还原将数据库恢复。此方法的前提条件是,需存在一份最近时间段内的完全数据库物理备份,以及数据库备份时间到故障时间点的完整归档日志,同时备份文件通过校验是完整的。
5.Roll文件误删除或损坏
当数据库ROLL.DBF文件误删除或损坏,数据库无法启动时,可以使用物理备份还原的方式,将数据库还原到指定的时间节点。
6.其他数据文件误删除
如果运行过程中DBF文件被误删除,可以通过以下两种方式恢复数据库。
方法一:通过备份还原将数据库恢复到指定时间点。(推荐使用)
注意:
如果在Linux环境下,可能对该文件还存在镜像,可以从proc中进行冷拷贝操作尝试还原,Windows下不适用这种办法。
方法二:若数据文件被删除,数据库还在运行,可使用导出导入或dts或者DMHS抽取数据的方式,进行数据库重建。
数据文件丢失后达梦数据库服务在一段时间内还能运行,当然数据库是存在风险的,此时不要关闭数据库服务。应立即使用达梦数据迁移工具DTS或逻辑导出导入工具将数据迁移到一个新的实例上,新的实例上需要创建和故障实例一样的表空间和数据文件、用户名,为每个用户分配表空间。通过查询DBA_USERS可以获取用户名和表空间、数据文件的对应关系。
SELECT USERNAME,DEFAULT_TABLESPACE,PROFILE from DBA_USERS;
(二)数据误修改或删除
1.表数据误修改
运维过程中经常会直接在数据库客户端上直接执行一些语句对数据进行修改,难免出现误操作的情况。任何时候在生产环境中直接用客户端操作,需要保证相关工具会话属性的自动提交是关闭状态,如果误操作的话,还可以简单的通过rollback直接补救。
如果出现误操作并提交,最安全的办法依然是通过备份恢复到尽可能新的状态。如若备份、归档存在问题,则需要其他的方式进行处理,对于错误插入,在DM的每一行数据上,都存在trxid伪列,一般情况误插入如果是批量的,通过查询相关事务号进行分组,确认批量行数,结合检查数据一般是可以找到问题数据再进行清理。
2.表数据误删除
当数据发生删除并提交时,实际的数据还是存在于数据文件上,只是该行数据被打上了删除标记,被打上删除标记的数据对查询是不可见的,并且在 dm.ini 文件中配置的 undo_retention 时间后,有删除标记的数据会被完全清理,在数据文件上就不可见了。如果启用了闪回查询,出现此类问题时,可直接通过闪回查询指定时间点,可以将不可见的数据直接返回到数据库客户端上,然后将这些数据进行落地保存,用于后续的修复。
如果开启了逻辑附加归档,可以通过dbms_logmnr工具对逻辑附加归档进行分析,分析完成后获取相关数据信息,用于数据回填。对删除而言,logcommit日志里面记录的内容作用有限,因为很可能只记录了删除语句本身以及相关where条件信息,没有实际的数据。
如果以上条件均不满足,可能的情况下,尽量杀掉数据库进程,并且防止自启,如果正常关闭和启动会对删除标记数据进行清理,直接杀掉数据库进程可以抓取误删除的表所在的表空间的相关数据文件,原厂工程师在一定情况下可以通过直接解析该文件,将该表相关数据进行还原。
(三)误操作数据库进程
1.kill数据库进程
在数据库正常运行中,由于误操作kill掉数据库实例进程,在重启数据库服务的时候报错数据库损坏,无法正常启动。
找到已损坏的数据库备份文件和归档文件,重新初始化实例,使用备份文件加归档的方式还原到kill之前的时间点,复用原实例的dm.ini参数,重新启动数据库服务,由于是新初始化的实例,redo默认是256,需要手动调整为2048。
2.数据库目录权限和所属用户/组被错误修改
在数据库系统正常运行期间,由于用户权限管理不当,数据库目录的权限和所属用户/组被错误地修改。为了保障数据库的安全性和稳定性,需要恢复数据库目录的权限和所有权至预期状态,并确保仅由指定的数据库管理员用户(如dmdba)进行管理和维护。首先,通过系统命令(如ls -ld /home/dmdba/dmdbms)检查/home/dmdba/dmdbms目录的当前权限和所有权设置,然后使用chown命令将数据库目录/home/dmdba/dmdbms的所有权更改为dmdba用户,并将其所属组更改为dinstall组。命令如下:
chown -R dmdba:dinstall /home/dmdba/dmdbms