与数据坏页的战争——一次Db2数据库损坏的修复过程 | 运维进阶
【摘要】本文记录了一次数据库损坏的故障,经过一波三折的修复过程,最终恢复了数据库的正常运行。
【作者】黄工,就职于上海新炬,负责某省移动的DB2及MYSQL数据库维护、管理。擅长DB2数据库维护,DPF、HADR架构安装部署及维护优化。MYSQL数据库安装、主从搭建及维护优化等。
敌情出现
对于数据库系统来说,数据安全的重要性是要放在首位的,所以从主机到存储、从操作系统到数据库系统、从硬件到软件都在为数据安全而努力,为了数据安全推出了很多技术。比如 Db2 数据库方面就有事务日志、日志归档、数据库备份、 HADR 等等。但是不管多先进、多成熟的技术,如果人员操作不规范、安全管理不到位,这些技术都保护不了数据的安全。
本人就遇到了操作不规范导致数据库损坏的故障。
元旦过后没几天,接到某客户的报障,主机运维厂家在更换存储控制器时出现了问题,导致他们的 Db2 数据库宕库,后来起库的时候无法启动,希望我们帮忙处理。一听到这,就意识到问题是很严重的,进一步了解到当时的情况:数据库所在的存储服务器有一个存储控制器坏了,因为有冗余,所以存储服务器还可以正常运行,但是需要更换故障的控制器。因此就计划在周五晚进行更换,本来这种更换的操作是存在风险的,需要停库停机更换。但操作方认为还有一个控制器在运行,存储正常,就在没停库停机的情况直接在线更换了。但是更换的时候出现问题导致存储故障,最后导致数据库宕库,后来他们在启动数据库的时候就出现错误,数据库无法启动。了解到这个情况就知道这个问题非常严重。
这套数据库为 DPF 多分区数据库,共有 3 台主机、 33 个节点,其中 0 节点在 1 号主机上,其它两台主机分别部署 16 个节点,数据库大小约为 80T 。部署之后至今没做过任何备份,因此无法通过备份来恢复数据库。因此只能在现有的库进行处理了。下面就是这次修复数据库的过程,希望对各位有所帮助。
分析敌情
首先自己尝试启动实例,所有节点实例节点启动成功。
实例启动成功后重启数据库,在重启数据库时出现了错误。
可以看到有部分节点的数据库启动成功,部分节点的启动失败。检查一下各节点的进程发现报错的节点实例进程已经宕掉了。
从检查结果来看, 部分节点实例已经宕掉了,而宕掉的实例全部在 2 号主机上。
从上面的情况来看,因为实例可以正常启动,但数据库启动失败,而数据库是异常宕库后启动的,启动后需要进行奔溃恢复数据库。初步判断是在进行奔溃恢复时出现了异常,而出现异常的全部在 2 号主机的节点,因此下面先检查 2 号主机节点数据库的 diagr 日志,检查如下,只列出重点关注的信息:
从上面的检查情况可以知道故障发生的大体过程: 15 节点在启动后进行了奔溃恢复,然而在恢复过程中遇到了有表数据页出现‘ CBIT verification error ’ CBIT 验证错误,也就是遇到了数据坏页,为了保护数据一致性,当数据库遇到坏页时会触发宕库。。而其它节点检测到该节点因为数据坏页宕掉后也触发了自身宕库,因此就出现了上面检查到的 2 号主机所有节点实例全部宕掉的情况。一般在数据库中如果存在坏页的话,只有在使用到该数据页时才会检测到坏页并触发宕库,而在以往遇到这种情况时都是将表 drop 掉然后从其它地方导入数据来恢复。然而此次是在数据库恢复过程中遇到的坏页,而此过程又是必不可少的,因此不可避免的就会遇到坏页并触发宕库。
根据 IBM 官方的说明, CBIT 校验是通过检查数据页磁盘页面校验码是否一致来确实数据页是否正常。如果出现 CBIT 校验错误,一般是由于数据库外部原因导致数据坏页,比如 OS 层面或者存储层面导致的数据坏页。这样也就印证此次数据库故障是由于主机更换存储控制器时存储出现异常导致了数据库宕库。
对敌宣战
知道了故障的原因,下面就是制定解决方案了。按照 IBM 官方说明,如果出现 CBIT 校验错误,最可行的方法是从备份中恢复数据库或表空间,但这个库未做过备份,因此此方法不可行。
此外有两种方案可选:
一、修复原数据库,通过 db2dart 工具将遇到坏页的表跳过,从而可以让数据库启动,后面再恢复这些表的数据,此方式适用于遇到坏页表数量不多的情况下,如果坏页表数量度,处理的时间就会很长。
二、异机恢复数据库,找一套性能与原库一样的主机,重搭建一套新库,数据库表空间、缓冲池、表、索引、视图等数据库对象可在原库通过 db2look 导出相应的创建语句来创建,然后使用 db2dart 工具将原库的表数据导出导入的方法来恢复。由于原库数据量很大,因此消耗的时间会很长。
最后与客户讨论建议先采用方案一,但是如果坏页表太多导致在限定时间内无法完成数据库修复的话,就采用方案二来恢复数据库。
这里重点介绍一下 Db2 数据库一个很重要的工具 db2dart : db2dart 工具可以用来验证数据库及其对象的体系结构是否正确。还可以使用它来显示数据库控制文件的内容,以便从其他情况下可能无法访问的表中抽取数据。 db2dart 是通过从磁盘中直接读取表数据页信息,因此要使用 db2dart 工具就必须停止数据库,也因此非常适用于数据库的无法启动情况下来修复数据库或者导出表数据。此次故障处理就是使用 db2dart 工具来修复数据库的。
获取数据库编目信息
首先就是要获取数据库的编目信息,过程如下:
过滤坏页表
获取数据库编目信息后接下来就是将坏页的表先过滤掉,此时数据库已停止。过程如下
首先在检查数据库 diag 日志中出现的坏页信息
通过上面红色标记的信息可以知道: 15 号节点的 27 号表空间的 1173 表有 CBTI 校验问题,需要处理这张表,使用 db2dart /MT 将表置为无效。这里需要说明一下 db2dart 的 /MT 参数在官方文档中查不到相关的说明,因为这是 IBM 内部使用的参数,需要 IBM 官方提供操作密码。客户那边通过 IBM 800 拿到了操作密码。操作过程如下:
将表置为无效后,进行重启实例、激活数据库操作,因为已将上面有坏页的表置为无效,因此在数据库恢复过程中不会恢复该表,但有可能遇到其它坏页的表。后面按照上面的方法继续处理了几张表。
但是在处理其中一张表时遇到了过滤表失败的情况,详情如下:
上面的操作记录说明在过滤 32 号表空间中 169 号表时出现了错误导致过滤该表失败。咨询了 IBM 800 后得知, db2dart /MT 是通过对表中的 0 页写入数据来将该表置为‘无效’,而该操作出现错误说明表中的 0 页也出现了损坏,导致无法将数据写入到 0 页。根据 IBM 的建议将该表所在的表空间进行过滤掉来启动数据库。通过之前的巡检记录查到该表空间总大小约 140G 。而也将表空间中的表发给客户确认了只需要部分表数据即可,其它的表则需要重建表而不需要表数据。下面就进行过滤表空间的操作。
首先在过滤该表空间前需要将表空间里的数据取出来。
在数据库停库的情况使用 db2dart 加 /DDEL /RPTN 参数将指定的表数据导出,该参数无需操作密码。对于多分区环境,该命令只在当前节点操作,可以通过 export DB2NODE=X 切换到指定的节点,因为表比较多,因此通过执行脚本来自动导出这些表,脚本内容如下:
在上面脚本中通过 N=X 来指定数据库节点号,每个节点一个脚本,这样就可以并行来导出表数据,提高速度。
通过执行导出脚本将表数据库导出完成后,就开始过滤表空间操作,操作如下:
在上面启动数据库过程也遇到了坏页的表,然后按照过滤表的方法继续操作,终于在经过两个小时的操作后成功启动了数据库,这说明 在恢复数据库过程没遇到坏页,但不代表在后面业务使用中不会遇到坏页。启动数据库后检查数据库状态、表空间状态、表状态、 diag 日志,确认数据库正常后通知业务侧启动业务测试。
在后面的业务测试中也遇到了数据坏页,继续按照上面的过滤方法来操作。终于在后面业务测试中基本没遇到坏页情况。数据库及业务情况慢慢稳定了下来。后面就是将坏页的表恢复回来。
恢复表数据
通过上面的操作后数据库已经可以正常运行,但已经过滤的表及表空间依然不可用,需要恢复这些表。而根据客户确认了全部表都需要新建,但只需要恢复部分表的数据即可。
首先恢复 32 号表空间的表,过程如下:
表空间及表创建完成后即可将之前导出的数据导入到表中
导入完成后检查导入信息无报错、检查表空间、表状态正常后通知客户对这些表进行操作。最后客户确认业务均恢复正常可用了。
至此这场与数据坏页的战役就胜利的结束了。
战后总结
从此次故障来看,是因为部分维护人的数据安全意识比较薄弱,对于数据库的安全重视不够、没有敬畏心。在没有停库的情况就进行更换硬件这种高风险的操作。而数据库本身也不做安全保障,没有进行数据备份,甚至连重要数据备份都没有。
还是那句话,数据安全无小事,对数据库安全要时时保持敬畏之心。
如有任何问题,可点击文末阅读原文到社区原文下评论交流
资料/文章推荐:
DB2数据库HADR部署三个难点问题
http://www.talkwithtrend.com/Article/244027
Db2数据库SQL语句的性能调优
http://www.talkwithtrend.com/Article/240583
欢迎关注社区 “数据库”技术主题,将会不断更新优质资料、文章。地址:
http://www.talkwithtrend.com/Topic/597
下载 twt 社区客户端 APP
与更多同行在一起
高手随时解答你的疑难问题
轻松订阅各领域技术主题
浏览下载最新文章资料
长按识别二维码即可下载
或到应用商店搜索“twt”
*本公众号所发布内容仅代表作者观点,不代表社区立场