一、前言
1.1 简介
数据库在运行过程中一般情况下处于相对稳定的状态,大多数严重故障是由于人为操作失误导致,例如误删除文件、错误修改或替换文件等。大多数人为操作故障如果严格按照规范化操作来都可避免,如果人为操作导致数据库故障实际已经发生,尽量避免进一步操作,应及时进行反馈,制定解决方案。以下将从文件误删除或损坏、数据误修改或删除两个个方面来分析人为操作类故障。
- 文件误删除或损坏
- 数据误修改或删除
1.2 术语与工具
- 伪列:指在物理上这个列并不存在,只是在查询时才构造出来。伪列通常是自由分配的,用户无法执行修改等操作。
- Dmmdf 工具:主要对 DM 相关的文件的属性进行修改。 支持的修改的文件类型有:dbf、rlog、original bak、bakset meta、bakset bkp、bakset,根据文件的不同,可修改的属性也有所不同,最主要的是修改 db_magic。
- dmctlcvt 工具:文件类型转换工具,在 DM 服务器关闭的状态下对控制文件进行修改,可将控制文件转换为文本文件或将文本文件转换为控制文件。
1.3 适用范围
本文中所涉及内容适用于 DM7 及 DM8 版本数据库产品。
二、文件误删或损坏
DM 数据库实例包含数据文件部分和执行文件部分:
- 数据文件是通过 DM 的实例初始化工具初始化的实例文件,包含数据文件(DBF 文件)、配置文件(ini 文件)、控制文件(ctl 文件)以及一些其他必须的文件 (dm_service.prikey) 等;
- 执行文件即通过 DM 的安装包安装后在目标机器上存在的可执行程序以及动态库。若此类文件在运行过程中被误删除,可能导致异常情况。
2.1 执行文件误删除
在 Windows 环境下,执行文件在被引用过程中是无法被删除的,出现此类问题的情况比较少,但在 Linux 环境下,数据库进程存在的情况下,相关执行文件可以被删除,程序会继续运行,但是运行过程中的日志等文件在程序执行完后可能会丢失,此情况下,通过查询 dmserver 的进程 pid,然后进入到 /proc/pid/cwd 路径下,仍然可以看到执行过程中依赖的相关文件,可以通过拷贝命令将相关文件拷贝存放,供后续使用。
2.2 控制文件误删除
控制文件,即 dm.ctl 文件,其中记录了数据库实例相关信息、数据版本信息和重做日志文件、数据文件路径属性等,如果被异常删除,表空间属性相关修改可能出现异常,如果不能正常修复,可能导致某些数据文件、REDO 日志文件没有被数据库实例纳入到管理范围,引发其他的严重问题。
如果发现该文件被异常删除,需要及时对该文件进行恢复,DM 数据库自身定期会对该文件进行备份,dm.ctl 文件的备份路径可以在 dm.ini 中进行配置。
- 进入 dm.ctl 文件的备份目录
- 在该目录下找到最接近故障时间的 dm.ctl 备份文件。
- 通过 $DM_HOME/bin 目录下的 dmctlcvt 工具将 dmctlcvt 转换成可读的 txt 文件。
- 打开 txt 文件,通过数据库客户端进行查询 vdatafile 以及 vrlogfile,以动态视图结果为准仔细检查各个文件是否可以和 txt 文件中的配置逐一对应,如果存在差异,手工对 txt 文件中的内容进行修改。
- 修改完成后,通过 dmctlcvt 工具将 txt 文件转换成 ctl 文件,移动到 dm.ini 中配置的 ctl 文件路径下,至此修复完成。
2.3 dm_service.prikey 文件误删除
实例的 RSA 钥文件涉及数据库一些重要数据的加解密,误删除无法简单处理,需要联系原厂工程师进行支持。
DM 在运行过程中会定期对这些比较重要的文件进行存在性检查,如果异常会在数据库运行日志中,巡检时需要留意。
2.4 REDO 日志文件误删除或损坏
REDO 日志文件默认在数据库实例下以实例名 .log 命名,该文件记录的是数据库运行过程中对数据文件修改的日志信息,并且相关的修改信息达到一定的条件才会实际被应用在数据文件上,如果误删除,首先在日志上没有被应用的日志信息涉及的数据将丢失,此外可能导致数据库无法正常启动。当数据库 redo 日志文件误删除或损坏,数据库无法启动时,分为以下两种方式恢复数据库:
方法一:使用物理备份还原的方式,将数据库还原到指定的时间节点
首选的恢复方式是通过备份还原,由于归档文件中如实的记录了 REDO 日志的信息,所以 REDO 日志中涉及的数据可以通过备份还原将数据库恢复。此种方法的前提是条件,需存在一份最近时间段内的完全数据库物理备份,以及数据库备份时间到故障时间点的完整归档日志,同时备份文件通过校验是完整的。详情见备份还原章节.
方法二:使用 dminit 工具重新初始化实例,替换 redo 日志文件文件。
如果备份还原不可用,或者归档丢失,就只能通过替换重做日志文件的方式对库做应急处理,如下所示:
-
通过 dminit 工具初始化一个新的实例,相关参数与故障库中的 dminitxxxx.log 中的配置保持一致;
-
将新建实例正常启动并停止一次;
-
将新实例的重做日志文件拷贝到故障库下;
-
使用 $DM_HOME/bin 目录下的 dmmdf 工具通过 SYSTEM.DBF 文件查看故障实例的 db_magic 值和 pemnt_magic 值;
./dmmdf type=1 file=/home/dmdba/dmdbms/data/DAMENG/SYSTEM.DBF
-
用 dmmdf 工具按照故故障实例的 db_magic 值和 pemnt_magic 值修改拷贝过来的重做日志文件的 db_magic 值和 pemnt_magic 值;
-
将原 redo 日志文件 mv 移走,使用新 redo 日志文件进行替换。
-
使用 dbcheck 工具检查数据文件是否损坏;
-
一切正常后,数据库可以正常启动。
警告替换 redo 属于危险操作,需要达梦技术团队进行评估,并且得到用户允许,充分考虑到操作的风险范围和回退措施,谨慎操作!此类方法在集群环境下不适用,新建重做日志会导致集群不可用。
2.5 Roll 文件误删除或损坏
当数据库 ROLL.DBF 文件误删除或损坏,数据库无法启动时,可以通过以下三种方式恢复数据库。
方法一:使用物理备份还原的方式,将数据库还原到指定的时间节点,详情见备份还原章节
方法二:调整 pseg_recv 参数跳过回滚段;
参数说明:
参数名 | 默认值 | 属性 | 说明 |
---|---|---|---|
pseg_recv | 3 | 动态,系统级 | 系统故障重启时,对活动事务和已提交事务的处理方式。 0:跳过回滚活动事务和 PURGE 已经提交事务的步骤。 在回滚表空间出现异常、损坏、系统无法正常启动时,可将 PSEG_RECV 设置为 0,让系统启动; 但存在一定风险,未提交事务的修改将无法回滚,破坏事务的原子性; 另外,已提交未 PURGE 的事务,将导致部分存储空间无法回收; 1:回滚活动事务并 PURGE 已经提交事务; 2:延迟 PURGE 已提交事务,延迟回滚活动事务; 3:回滚活动事务,延迟 PURGE 已提交事务 |
方法三:使用 dminit 工具重新初始化实例,替换 ROLL.DBF 文件。
- 初始化新实例相关参数需和旧实例一致,可通过管理工具或 show 备份文件进行查看,该处初始化实例后 ROLL.DBF 大小和原库需保持一致,可通过 sql 语句进行修改
- 正常启动和停止一次数据库服务;
- 将原 ROLL.DBF 文件 mv 移走后,使用新 ROLL.DBF 文件进行替换。
警告替换 roll 属于危险操作,需要达梦技术服务团队进行评估,谨慎操作!
2.6 其他数据文件误删除
如果运行过程中 DBF 文件被误删除,可以通过以下两种方式恢复数据库。
方法一:通过备份还原将数据库恢复到指定时间点。(推荐使用)详情见备份还原章节
注意如果在 Linux 环境下,可能对该文件还存在镜像,可以从 proc 中进行冷拷贝操作尝试还原,Windows 下不适用这种办法。
方法二:若数据文件被删除,数据库还在运行,可使用导出导入或 dts 或者 DMHS 抽取数据的方式,进行数据库重建。
数据文件丢失后达梦数据库服务在一段时间内还能运行,当然数据库是存在风险的,此时不要关闭数据库服务。应立即使用达梦数据迁移工具 DTS 或逻辑导出导入工具将数据迁移到一个新的实例上,新的实例上需要创建和故障实例一样的表空间和数据文件、用户名,为每个用户分配表空间。通过查询 DBA_USERS 可以获取用户名和表空间、数据文件的对应关系。
SELECT USERNAME,DEFAULT_TABLESPACE,PROFILE from DBA_USERS;
三、数据误修改或删除
3.1 表数据误修改
运维过程中经常会直接在数据库客户端上直接执行一些语句对数据进行修改,难免出现误操作的情况。任何时候在生产环境中直接用客户端操作,需要保证相关工具会话属性的自动提交是关闭状态,如果误操作的话,还可以简单的通过 rollback 直接补救。
如果出现误操作并提交,最安全的办法依然是通过备份恢复到尽可能新的状态。如若备份、归档存在问题,则需要其他的方式进行处理,对于错误插入,在 DM 的每一行数据上,都存在 trxid 伪列,一般情况误插入如果是批量的,通过查询相关事务号进行分组,确认批量行数,结合检查数据一般是可以找到问题数据再进行清理。
3.2 表数据误删除
当数据发生删除并提交时,实际的数据还是存在于数据文件上,只是该行数据被打上了删除标记,被打上删除标记的数据对查询是不可见的,并且在 dm.ini 文件中配置的 undo_retention 时间后,有删除标记的数据会被完全清理,在数据文件上就不可见了。如果启用了闪回查询,出现此类问题时,可直接通过闪回查询指定时间点,可以将不可见的数据直接返回到数据库客户端上,然后将这些数据进行落地保存,用于后续的修复。
如果开启了逻辑附加归档,可以通过 dbms_logmnr 工具对逻辑附加归档进行分析,分析完成后获取相关数据信息,用于数据回填。对删除而言,logcommit 日志里面记录的内容作用有限,因为很可能只记录了删除语句本身以及相关 where 条件信息,没有实际的数据。
如果以上条件均不满足,可能的情况下,尽量杀掉数据库进程,并且防止自启,如果正常关闭和启动会对删除标记数据进行清理,直接杀掉数据库进程可以抓取误删除的表所在的表空间的相关数据文件,原厂工程师在一定情况下可以通过直接解析该文件,将该表相关数据进行还原。
四、参考
若以上内容无法解决您的问题,可以在达梦技术社区提问交流。