本文共总结了企业核心系统数据库在以下7个意外场景下宕机或者无法连续的对外提供服务的应急解决方案。本文旨在帮助运维人员在企业关键业务系统的数据库在宕机后如何在最短的时间内恢复业务并最大化保证数据的完整性与一致性。这也是本方案设计的初衷~希望该文中的部分内容能够给博友们一点思考和启发或则一点点帮助~尤其是奋斗在一线的苦逼运维兄弟们~
一、核心业务系统数据库crash场景清单:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1、数据库异常崩溃恢复
2、活动日志文件丢失或损坏
3、非关键数据文件丢失或损坏
4、关键数据文件丢失或损坏
5、循环日志满
6、表空间满
7、误删数据库表或表数据
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
二、以下场景的应急恢复步骤均以模拟db2数据库出现故障为前提给予了详细应急解决方案。
1.1 数据库异常崩溃恢复
场景描述:
本场景假设对数据库执行的事务可能被异常中断,如果作为事务的一部分的所有更改完成和提交之前发生故障,那么数据库将处于不一致和不可用状态。崩溃恢复是将数据库恢复为一致并可用状态的过程。
场景(一):数据库处于崩溃状态
应急处理步骤:
1)设置autorestart 参数为on
#db2 update db cfg for dbname using AUTORESTART on
2)或手动重启数据库
# db2 restart database dbname
db2数据库自动检测数据库一致性和完整性状态并修复,最后使数据库处于可用和一致性状态。
场景(二):数据库IO在发生崩溃之前已处于暂挂的状态
应急处理步骤:
1)重启数据库并进行崩溃恢复操作
#db2 restart database dbname write resume
1.2 活动日志文件丢失或损坏
场景描述:
本场景模拟DB2 的活动日志文件丢失、损坏或者所在的存储设备出现问题,则不可避免地造成 DB2 数据库系统宕机。
方法一、使用备份恢复数据库
应急处理步骤:
1) 将最近备份的日志从带库retrieved到服务器/odsdbbak目录
#dsmc retrieve /source_path/file /dest
2) 查找损坏的LSN
#db2flsn ./sqllib/db2ump/db2diag.log
#查看时间戳,该时间戳之前的都要恢复。
3)使用以下命令开始前滚恢复数据库并恢复到指定的时间点(建议将以下内容放到脚本里面执行)
#db2 force application all
#db2 restore db dbname from /odsdbbak taken at timestamp on /odsdatabase logtarget /odsdbbak/tmplog
#db2 "rollforward db dbname to timestamp using local time and stop overfiow
log path("/odsdbbak/tmplog") "
方法二、对于因硬件故障导致的日志丢失或者损坏致电 8008101818-5200重置日志控制文件,提供 ICN或PPA Number,对于生产系统宕机,IBM提供 7*24小时服务。
1.3 数据文件丢失或损坏
场景描述:
本场景模拟了关键与非关键数据文件丢失后的应急解决方案。损坏问题可能会对系统造成严重的性能问题。在某些情况下,它可能会导致频繁的系统崩溃,引发关键业务系统宕机。数据库损坏可发生在任何层面,从 DB2 到操作系统以及硬件层。本案例中对于硬件故障暂不做探讨。从db2层面来看:损坏问题可以大体分为五个类别:数据页面损坏(或表损坏)、索引损坏、CBIT 损坏、日志损坏和压缩描述符损坏。
下面我们将根据以上5个分类分别列出对应的解决措施:
(一) 对于表损坏的应急措施如下步骤:
方法一:
1) 导出表结构
#db2look -d dbname -e -t tabname -o tab.sql
2) 使用 db2dart 以及 /ddel 从受损的表上挽救数据
# db2dart dbname /ddel
#该命令需要四个输入值:表对象 ID 或表名称,表空间 ID,起始的页码,以及页数。页数可以是一个具体的值或一个足够大的值才能提取表中的所有页面。在执行完毕db2dart后将生成带有del后缀的文件,该文件即为待恢复的数据文件。
3) 重建表
#db2 connect to dbname
#db2 -tvf tabl.sql
4) 恢复数据
#db2 “import from tab.del of del insert into tab”
方法二:选择恢复数据库相应表空间的恢复方法进行恢复损坏的表,具体请参见本文第六部分内容
(二)索引损坏应急步骤
1)调整dbname数据库参数INDEXREC 为 restart 或者 access来重建索引
# db2 update db cfg for dbname using INDEXREC ACCESS
#在更新 INDEXREC 之后即可连接到数据库
(三) CBIT (校验)损坏
从 CBIT 错误中恢复的最可行方法是还原数据库或表空间,具体应急步骤参考本文第六部分内容。
(四)日志损坏
请参考本文第二步操作步骤
(五)压缩描述符损坏
应急操作步骤:
方法一:
可以使用 db2cat 工具修复损坏的压缩描述符。在修改压缩描述符之前,请咨询 IBM 支持团队。
可以执行以下步骤来修正压缩的描述符:
1)export DB2SVCPW=service_password from IBM support
2)db2cat -d dbname -s schema -n tablename -f raw pd output file -o message file
3)db2cat -d dbname -s schema -n tablename -g generated pd output file -o message file
4)db2cat -d dbname -s schema -n tablename -r generated pd output file -o message file
5)从表中导出数据(如有需要)
#db2 “export to tab.ixf of ixf select * from tab”
6)删除表
#db2look -d dbname -e -t tabname -o tab.sql
#db2 drop table tab
7)重新创建表(如有需要)
#db2 connect to dbname
#db2 -tvf tab.sql
8)导入用户数据(如有需要)
db2 “import from tab.ixf of ixf insert into tab”
现在我们可以在数据库上再次运行 db2cat 的验证选项:db2cat -d dbname -s % -n % -v 。
方法二:参考本文第六部分内容进行数据库的恢复
1.4 循环日志满
场景描述:循环日志满是因为有大量的插入、更新、删除操作且未及时提交导致的结果(不含因归档日志满导致的循环日志满问题处理)。
场景(一):可以终止导致循环日志满的事务
应急处理步骤:
1)使用db2top工具得到大事务apphandle
#db2top -d dbname
#再按l查看log used使用最多的那个事务
1) force掉该事务
# db2 force application'(appid)'
场景(二):不能终止导致循环日志满的事务
应急处理步骤:
方法一:在线清理日志
1)取得当前活动日志
#db2 get db cfg for dbname|grep -i log
# First active log file 查看该参数指向的日志文件
2)在线清理日志
# db2 prune logfile prior to S0000***.LOG
方法二、在线增加辅助日志数量或大小(不含文件系统满导致的活动日志满问题处理)
1)在线调整大小
#db2 update db cfg for LOGSECOND using $num
1.5 表空间满
场景描述:表空间满的原因是由于数据库表数据量激增导致表空间满的结果。
应急措施:
第一种方法:扩展表空间大小
1)确认文件系统还有剩余空间,可使用如下命令进行扩展
#db2 connect to dbname
#db alter tablespace tbsname extend(file ‘tbs path’ 30G)
#或db2 "alter tablespace DIPUSR16K resize (device 'device path' 30G)"
第二种方法:为表空间添加新的容器
1)添加新的容器到指定表空间
#db2 alter tablespace tbsname add(device ‘device path’ 30G)
第三种方法:通过HA扩展相应LV大小
1.6 误删数据库表或表数据
场景描述:
如果发生了存储故障或者用户不小心误删了表中的重要数据或者表。这种情况下需要用到数据库前滚恢复。
方案一、恢复数据库
应急处理步骤:
1)将最近备份的日志从带库retrieved到服务器/odsdbbak目录
#dsmc retrieve /source_path/file /dest
2)使用以下命令开始前滚恢复数据库到指定的时间戳(建议将以下内容放到脚本里面执行)
#db2 force application all
#db2 restore db dbname from /odsdbbak taken at timestamp on /odsdatabase logtarget /odsdbbak/tmplog
# db2 "rollforward db dbname to timestamp using local time and stop overfiow
log path("/odsdbbak/tmplog") "
#db2 rollforward db dbname stop
方案二、恢复表空间
应急处理步骤:
方法一:适合syscatspace已丢失待回复该表空间的相关信息
1)将最近备份的日志从带库retrieved到服务器/odsdbbak目录
#dsmc retrieve /source_path/file /dest
2)使用以下命令开始前滚恢复数据库到指定的时间戳(建议将以下内容放到脚本里面执行)
#db2 “restore db dbname rebuild with tablespace(syscatspace,rptidx01) taken at timestamp” logtarget /odsdbbak/tmplog
#db2 "rollforward db dbname to timestamp using local time tablespace (syscatspace ,rptidx01) to end of logs overflow log path(/odsdbbak/tmplog)”
#db2 rollforward db dbname stop
方法二:适合syscatspace表空间保存有待恢复表空间的相关配置信息
1)将最近备份的日志从带库retrieved到服务器/odsdbbak目录
#dsmc retrieve /source_path/file /dest
2) db2 restore db dbname tablespace(odsidx01) taken at timestamp logtarget /odsdbbak/tmplog
db2 rollforward db dbname to timestamp using local time tablespace (odsidx01) to end of logs overflow log path(/odsdbbak/tmplog)