人为操作故障

DM 数据库实例包含数据文件部分和执行文件,执行文件即通过 DM 的安装包安装后在目标机器上存在的可执行程序以及动态库,数据文件是通过 DM 的实例初始话工具初始化的实例文件,包含数据文件(DBF 文件)、配置文件(ini 文件)、控制文件(ctl 文件)以及一些其他必须的文件 (dm_service.prikey) 等,若此类文件在运行过程中被误删除,可能导致异常的情况。

另外在运维过程中,可能存在对数据的误操作,更新、删除插入等,如果存在这种情况,也可能导致应用系统的问题。以下将对此类问题进行依次讲解。

误删文件/数据类

执行文件

在 Windows 环境下,执行文件在被引用过程中是无法被删除的,出现此类问题的情况比较少,但在 Linux 环境下,数据库进程存在的情况下,相关执行文件可以被删除,程序会继续运行,但是运行过程中的日志等文件在程序执行完后可能会丢失,此中情况下,通过查询 dmserver 的进程 pid,然后进入到 /proc/pid/cwd 路径下,依然可以看到执行过程中依赖的相关文件,可以通过拷贝命令将相关文件拷贝存放,供后续使用。

控制文件

控制文件,即 dm.ctl,记录数据库实例的实例相关信息、数据版本信息和重做日志文件、数据文件路径属性等,如果被异常删除,表空间属性相关修改可能出现异常,如果不能正常修复,可能导致某些数据文件、REDO 日志文件没有被数据库实例纳入到管理范围,引发其他的严重问题。

如果发现(一般在巡检中)该文件被异常删除,需要及时对该文件进行修复,DM 数据库自身定期会对该文件进行备份,ctl 的备份路径可以在 dm.ini 中进行配置

  • 在该目录下找到最接近故障时间的 ctl 备份文件。
  • 通过 $DM_HOME/bin 目录下的 dmctlcvt 工具(具体命令查看 dmctlcvt help)将 dmctlcvt 转换成可读的 txt 文件。
  • 打开 txt 文件,通过数据库客户端进行查询 v​datafile 以及 vrlogfile,仔细检查各个文件是否可以逐一对应,如果存在差异,以动态视图结果为准,手工对 txt 文件中的内容进行修改(增加或者删除相关文件描述)。
  • 修改完成后,通过 dmctlcvt 工具将 txt 文件转换成 ctl 文件,移动到 dm.ini 中配置的 ctl 文件路径下,至此修复完成。

dm_service.prikey

该实例的 RSA 钥文件,涉及基本的数据库一些重要数据的加解密,误删除无法简单处理,需要联系原厂工程师进行支持。

DM 在运行过程中会定期对这些比较重要的文件进行存在性检查,如果异常会在数据库运行日志中,巡检时需要留意。

重做日志文件

默认在数据库实例下存在以实例名 .log 命名的重做日志文件,该文件记录的是数据库运行过程中对实际的数据文件修改的日志信息,并且相关的修改信息达到一定的条件才会实际被应用在数据文件上,如若发生误删除,首先在日志上这些部分未应用日志信息涉及的数据一定就丢失了,另外可能导致数据库无法正常启动。

首选的恢复方式是通过备份还原,由于归档文件中如实的记录了重做日志的信息,所以 REDO 中涉及的数据通过备份还原并对归档的读取可以正常的将数据库恢复。

如果备份还原不可用,或者归档丢失等,只能通过替换重做日志文件的方式对库做应急处理,如下所示:

  • 通过 dminit 工具初始化一个新的实例,相关参数参考目前故障库的 dminitxxxx.log 中的配置保持一致。
  • 将新建实例正常启动并停止一次。
  • 将新实例的重做日志文件拷贝到故障库下。
  • 通过 $DM_HOME/bin 目录下的 dmmdf 工具查看故障库的数据文件的相关信息。
  • 用 dmmdf 工具按照前面查到的信息对拷贝过来的新重做日志文件修改两个 magic 值
  • 修改完成后,数据库可以正常启动。

此类方法在集群环境下不适用,由于重做日志记录的部分头部信息和实例间同步相关,新建重做日志会导致集群不可用,另外使用该方法正常启动后,以前未应用的部分数据会丢失,系统可靠性也会降低,只能临时用于启动数据库,需要尽快将数据迁出至健康环境。

数据文件

如果运行过程中 DBF 文件被误删除,首选的方式是通过备份还原对数据库进行最大长度的恢复(指定时间点),如果备份不存在或者不可用,在可能的情况下,尽可能快的停止一切对数据库的写操作(切断应用、网络),同样,如果在 Linux 环境下,可能对该文件还存在镜像,可以从 proc 中进行冷拷贝操作尝试还原,Windows 下这种情况可以处理的办法不多。

误修改文件/数据类

误修改数据 (upd del ins)

运维过程中经常会直接在数据库客户端上直接执行一些语句对数据进行修改,也不免出现误操作的情况。

  • 任何时候我们在生产环境中直接用客户端操作,需要保证相关工具的会话属性的自动提交是关闭状态,这样如果误操作的话,可以简单的通过 rollback 直接补救。
  • 如果出现误操作并提交,最安全的办法依然是通过备份恢复到尽可能新的状态,如若备份、归档存在问题,则需要其他的方式进行处理,这里着重讲一下这种情况的处理措施。
  • 对于错误插入,在 DM 的每一行数据上,都存在 trxid 伪列,一般情况误插入如果是批量的,通过查询相关事务号进行分组,确认批量行数,结合检查数据一般是可以找到问题数据再进行清理。

更新/删除操作

数据可能存在的地方如下:

  • 表所在表空间数据文件 (*.DBF)
  • 回滚表空间数据文件 (ROLL.DBF)
  • 重做日志 (DAMENG01.log 等)
  • 归档文件(物理)
  • 附加逻辑归档
  • Logcommit 日志

以删除 (DELETE/TRUNCATE) 为例,介绍如何进行数据恢复。

当数据发生删除并提交时,实际的数据还是存在于数据文件上的,只是该行数据被打上了删除标记,被打上删除标记的数据对查询是不可见的,并且在 ini 配置的 undo_retention 时间后,有删除标记的数据会被完全清理,在数据文件上就不可见了。如果启用了闪回查询,出现此类问题时,直接通过闪回查询指定时间点,可以将不可见的数据直接返回到数据库客户端上(UPDATE类似),然后将这些数据进行落地保存,用于后续的修复。

如果开启了逻辑附加归档,可以通过 dbms_logmnr 工具对逻辑附加归档进行分析,分析完成后获取相关数据信息,用于数据回填。对删除而言,logcommit 日志里面记录的内容作用有限,因为很可能只记录了删除语句本身以及相关where条件信息,没有实际的数据。

如果是 UPDATE 误操作,且不满足上述条件,如果存在物理归档,可以通过 $DM_HOME/bin 目录下的 dmlcvt 工具对归档进行分析(具体用法参考 dmlcvt help),分析表空间号为 1(ROLL.DBF)的所有记录,分析完成后,在分析结果中找到所有的 urec_upd 类型记录,该记录包含了更新涉及的 KEY,以及更新的旧值信息,均为二进制显示,通过原厂工程师提供解析方法,将此类信息还原成更新语句,直接执行更新语句可以将相关数据还原。

如果以上条件均不满足,可能的情况下,尽量杀掉数据库进程,并且防止自启动(正常关闭和启动过程中会对删除标记数据进行清理),抓取误删除的表所在的表空间的相关数据文件,原厂工程师可以通过直接解析该文件,将该表所有数据进行还原。

微信扫码
分享文档
扫一扫
联系客服