(转)Db2数据库一次生产故障详细记录---数据库坏页

原文:http://www.talkwithtrend.com/Article/216335

前言

数据库最严重的故障莫过于数据库损坏。数据库坏页是数据库损坏的一种,如果数据库中有数据页出现损坏,在没有访问到坏页时,数据库可以正常提供服务,当使用到坏页所在的表,有可能导致数据库的崩溃。

导致数据库出现坏页的可能性有很多,比如突然的掉电、主机down机,或者存储、磁盘的故障等等。

当数据库出现坏页时,首先使用操作系统命令判断是否出现硬件故障,修复硬件故障后,可以尝试使用"db2 restart db dbname"命令让数据库执行崩溃恢复,这种方法有可能恢复数据库的正常。如果不适用与上述方法,那么最好的办法就是从备份恢复数据库。

如果无法从备份恢复,那么在数据库可以连接的情况下,可以采用db2look导出表结构和export导出数据的方法来重建数据库。当然对于损坏的表,只能使用db2dart工具离线导出这些表的数据,处于坏页上的数据库极有可能丢失了。

如果数据库无法连接了,只能使用db2dart离线导出整个数据库的数据。导出数据之后,剩下的就是重建库并且导入数据了。

本文记录了一次生产环境中数据库页头的损坏的数据库坏页故障,经过一波三折的修复过程,最终恢复了绝大部分数据,恢复了数据库的正常运行。

环境介绍

操作系统版本 AIX 6100-07-04-1216
数据库版本 DB2 v9.7.0.7
该数据库比较大,大概2.2T,出现坏页的表数据量也比较大,大概30G。

一、问题发现

业务同事查询XXX数据库的某个报表查询,出现如下报错:

二、初步分析

查看该报错的解释:
db2 "? sql1655c"

查看数据库的nfy日志:
more db2npsh.nfy

2017-08-07-14.14.44.308129 Instance:db2npsh Node:000
PID:12517626(db2agent (NPSH) 0) TID:25497 Appid:*LOCAL.db2npsh.170807055005
buffer pool services sqlbReadPage Probe:1199 Database:NPSH
ADM6006E DB2 encountered an error while reading page "114482656" from table 
space "3" for object "1859" (located at offset "114482688" of container "/dev/rlvts_npsh_d8").

2017-08-07-14.14.55.313501+480 E1900111A837 LEVEL: Critical
PID : 12517626 TID : 11548 PROC : db2sysc 0
INSTANCE: db2npsh NODE : 000
EDUID : 11548 EDUNAME: db2pfchr (NPSH) 0
FUNCTION: DB2 UDB, buffer pool services, sqlbLogReadAttemptFailure, probe:10
MESSAGE : ADM14001C An unexpected and critical error has occurred: "BadPage". 
The instance may have been shutdown as a result. "Automatic" FODC 
(First Occurrence Data Capture) has been invoked and diagnostic 
information has been recorded in directory 
"/db2/dump/npsh/FODC_BadPage_2017-08-07-10.09.10.302693_0000/". 
Please look in this directory for detailed evidence about what 
happened and contact IBM support if necessary to diagnose the 
problem.

同时,也发现dump目录下生成FODC_BadPage的文件。

三、进一步分析

尝试定位出现坏页的表:
根据db2npsh.nfy 日志中的信息table space "3" for object "1859",查询如下:
db2 "select tabname,status from syscat.datapartitions where tbspaceid =3 and tableid=1859"
没有输出,怀疑是分区表的某个分区坏了,查询如下:
db2 "select tabname,DATAPARTITIONNAME from syscat.datapartitions where tbspaceid=3 and PARTITIONOBJECTID=1859"
输出如下:
NXXXXTRFH PART201707
可以判断是这个分区出现坏页。

查询该表的状态,正常:
db2 "select tabname,status,tbspaceid,tableid from syscat.tables where tabname=‘NXXXXTRFH‘"

从该表查询数据,正常:
db2 "select * from dbnpsh. NXXXXTRFH fetch first 10 rows only"

所以说数据库的坏页比较复杂,有时候坏页导致整个表故障,而本次,表面上查看起来,表数据一切正常。当跑报表访问到特定的页时才报出故障。

尝试通过load from cursor的方法把坏页的表分区的数据导出来,和报表查询语句报同样的错误:

尝试通过export导出数据:
db2 "export to /db2/archlog/npsh/NXXXXTRFH_PART201707.ixf of ixf select * from db2npsh.NXXXXTRFH_PART201707"
导出hang住,两个小时后,导出400多万数据,出现同样的报错,而且数据量明显不对

收集所有的日志信息,发送给IBM800协助进行分析问题。
db2support . -d npsh -c -s

经分析,IBM二线确认出现数据库坏页,建议使用db2dart导出表数据:

四、数据修复步骤

下面是数据找回的过程:

卸载表分区

由于该表大小达到30G,尝试将表分区卸载下来单独导出:
db2 alter table dbnpsh.NXXXXTRFH detach partition PART201707 into NXXXXTRFH_PART201707
卸载成功

db2dart准备工作

执行db2dart之前,需要准备两点:
1、断开所有数据连接
db2 force applicaitons all
2、扩容dump目录至能够放下整个分区的数据

db2dart导出数据

db2dart导出数据
开始执行db2dart导出数据:
db2dart npsh /DDEL 
然后输入:1859,3,0,999999
(四个参数的意义分别为:对象id,表空间id,起始页号,导出总页数)
IBM建议导出总页数设置为999999页

db2dart操作执行2小时,发现导出的页数已经达到999998,怀疑导出的页数超过设置的999999上限。看来IBM给的建议也不是完全准确。

将页数改为99999999,重新执行db2dart导出(需要先删除之前导出的dart目录):
db2dart npsh /DDEL 
然后输入:1859,3,0,99999999
历时三个小时后,导出成功,总共导出1100000多页。
导出文件名默认TS3T1859.DEL。

将dart出来的数据放入临时表

新建临时表NXXXXTRFH_PART20170702,注意指定的表空间要和NXXXXTRFH主表保持一致。

将dart出的数据导入到临时表:
db2 -v "LOAD FROM TS3T1859.DEL of del INSERT INTO DB2NPSH.NXXXXTRFH_PART20170702 NONRECOVERABLE"
导入出现“字段类型不匹配”的报错,经过排查,是由于该表包含DBCLOB大字段,这种字段dart命令无法导出。查询原表,发现该字段为空,庆幸不会丢失大字段数据,但是由于数据文件和表结构不匹配,导入成了一个问题。

有两种方案解决这个问题:
第一,编辑数据文件,定位到大字段那一列,插入一个逗号,即插入一列空列。

第二,新建不包含大字段列的表,导入数据后再添加大字段。

新建NXXXXTRFH_PART20170703不包含dbclob列,导入数据:
db2 -v "LOAD FROM TS3T1859.DEL of del INSERT INTO DB2NPSH.NXXXXTRFH_PART20170703 NONRECOVERABLE"
Number of rows read = 23771029
Number of rows skipped = 0
Number of rows loaded = 23770943
Number of rows rejected = 86
Number of rows deleted = 0
Number of rows committed = 23771029

添加列
db2 "alter table db2npsh.NXXXXTRFH_PART20170703 add column URL DBCLOB(2048) LOGGED NOT COMPACT"

执行成功。将临时表挂载到主表上

将临时表挂载到主表上:
db2 "alter table dbnpsh.NXXXXTRFH attach partition PART201707 starting (‘20170701‘) ending (‘20170731‘) from DB2NPSH.NXXXXTRFH_PART20170703"
挂载失败:
SQL20408N Table "DB2NPSH.NXXXXTRFH_PART20170703" cannot be attached to 
table "DBNPSH.NXXXXTRFH" because column "PAYEENM" of the source table and 
its associated column "URL" of the target table do not match. Reason code = "8". SQLSTATE=428GE

经分析,原因是临时表的列顺序和主表不一致。

解决方法:
将03临时表的数据通过指定列的方式insert到02临时表:
db2 -v "INSERT INTO DB2NPSH.NXXXXTRFH_PART20170702 SELECT MSGID,INSTGBKID,MSGCD,SEQNB,INSTGDRCTPTY,BIZTYP,BIZKIND,SYSCD,REGTIME,TRANCHNLTYP,CREDTTM,INSTDDRCTPTY,INSTDPTY,RMK ,PAYERNM,PAYERDPSTBKNM,DBTRDPSHDL,PAYERTELE,PAYERACCTNO,PAYERACCTYP,PWD ,PYMTAGRMT,AUTHPYMTBIZKIND,PTCID,URL,PAYEENM,CDTRDPSHDL,PAYEEDPSTBKID,PAYEEDPSTBKNM,PAYEEACCTNO,ACCTLTD,AGRINEFFCTVDT,AGREFFCTVDT,SNGLTXAMTLMT,ORIGMSGID,CSTMRNB,CDTRCSTMRID,DLTTLCNT,DAYAMTUPPERLMT,CURCD,MSLTTLCNT,MTHAMTUPPERLMT,MAGETYP,ACQFEE,CLRDATE,BIZPRCSCD,BIZRJCTCD,BIZRETSTS,RJCTRESN,BIZSTS,CTRLIND,BIZBIGTYP,ADDINFO1,ADDINFO2,ADDINFO3,ADDINFO4,ADDTBNM,SIGNATURE,TRADEFLAG,RPLIRACCT,RPLIRNM,RPLIRDPSNM,RPLIRDPSHDL,RPLIRACCTTP,QRISTACCT,QRISTNM,QRISTPTYNM,QRISTPTYHDL FROM DB2NPSH.NXXXXTRFH_PART20170703"

将02临时表挂载到主表:
db2 "alter table dbnpsh.NXXXXTRFH attach partition PART201707 starting (‘20170701‘) ending (‘20170731‘) from DB2NPSH.NXXXXTRFH_PART20170702"
挂载成功
SQL3601W The statement caused one or more tables to automatically be placed 
in the Set Integrity Pending state. SQLSTATE=01586

一致性检查

进行一致性检查:
db2 set integrity for dbnpsh.NXXXXTRFH immediate checked

执行大概十分钟,成功。
DB20000I The SQL command completed successfully.

数据量确认

查询201707分区的数据量:
db2 "select count(*) from DBNPSH.NXXXXTRFH where CLRDATE>=‘20170701‘ and CLRDATE<=‘20170731‘"
导入数据总条数:23770943

原数据条数:
db2 "select count(*) from DB2NPSH.NXXXXTRFH_PART201707"
原数据总条数:23771388
损坏的数据条数:23771388-23770943=445条

至此,数据恢复完成,找回23770943条数据,损坏445条。

时间: 2024-12-22 23:27:37

(转)Db2数据库一次生产故障详细记录---数据库坏页的相关文章

MySQL数据库 | 数据表-查询命令详细记录

本篇专门记录数据库增删改查中最常用.花招最多的 查. [文章结构] 一.数据的准备 二.基本的查询功能 三.条件查询 四.查询排序 五.聚合函数 六.分组查询 七.分页查询 八.连接查询 九.子查询 十.自关联 [正文] 一.数据的准备 首先创建一个数据库,以便后文命令的使用. -- 创建一个数据库 create database pysql charset=utf8; -- 使用数据库 use pysql; -- 查看当前使用的是哪个数据库 select database(); -- 创建数据

DB2日常维护——REORG TABLE命令优化数据库性能

[转]DB2日常维护——REORG TABLE命令优化数据库性能 一个完整的日常维护规范可以帮助 DBA 理顺每天需要的操作,以便更好的监控和维护数据库,保证数据库的正常.安全.高效运行,防止一些错误重复发生. 由于DB2使用CBO作为数据库的优化器,数据库对象的状态信息对数据库使用合理的 ACCESS PLAN至关重要.DB2 优化器使用目录统计信息来确定任何给定查询的最佳访问方案.如果有关表或索引的统计信息已过时或者不完整,则会导致优化器选择不是最佳的方案,并且会降低 执行查询的速度.当数据

mongodb 3.2.5安装过程详细记录

2016-10-19    mongodb 3.2.5安装 1 准备安装介质 安装介质下载: mongodb的安装方式,我通常使用二进制包的方式,内网不能配置连接外网的yum源: 官方建议的mongodb下载地址为:   Downloads.mongodb.org 但实际上,这个地址,很难找到下载表,正常下载,通常可以用下面的下载地址选择下载: 我这里下载的是: 3.2.5 版本对应的 mongodb-linux-x86_64-rhel62-3.2.5-20-g07e21d8.tgz 如果将整个

超强、超详细Redis数据库入门教程

这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 – 简介8.redis数据结构 – strings9.redis数据结构 – lists10.redis数据结构 – 集合11.redis数据结构 – 有序集合12.redis数据结构 – 哈希13.聊聊

iOS数据库操作之coredata详细操作步骤

CHENYILONG Blog iOS数据库操作之coredata详细操作步骤 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong iOS应用数据存取的常用方式 ? XML属性列表 -- PList? NSKeyedArchiver 归档 ?Preference(偏好设置) ? SQLite3? Core DataCore Data简介 ? Core Data 是iOS SDK 里的一个很强大的

MVC显示详细记录Without Entity Framework

看过此篇<MVC用非Entity Framework将数据显示于视图(二)>http://www.cnblogs.com/insus/p/3364482.html 了解到把数据库中数据表的数据显示于视图上.某一情况,我需要点击一下记录,能查看到其详细的数据. 在MVC实现这样的功能,其实也是很简单的.我们可以先在数据库中创建一个存储过程([dbo].[usp_FruitCategory_GetByPrimarykey]): 传入记录的主键值,来获取记录.去修改Models目录下的FruitCa

详细记录ASP.NET中的图象处理

最近做网站时,要求上传能加上水印,就研究了一下相关的功能.推荐一下程序人生的网站,大家也可以写一些开发感悟在上面.在使用ASP的时候,我们时常要借助第三方控件来实现一些图象功能.而现在,ASP.NET的推出,我们已经没有必要再使用第三方控件来实现,因为ASP.NET 已经具有强大的功能来实现一些图象处理.现在,我们就来看看怎样使用ASP.NET的这一强大功能.      一.System.Drawing的使用   以下的举例将演示在内存中生成一张图片,然后,将这张图片通过网页显示出来.需要了解的

Maven 搭建SpringMvc+Spring+Mybatis详细记录

总觉得,看比人写的总是那么好,每次搭建框架时都会找博客,找教程来跟着一步一步走,虽然很快搭建成功了,但是经常情况是我并不知道我干了什么,也不记得具体步骤,到底为什么要这么做,今天我详细记录了一下自己搭建的过程,并且尽量理解每一步干什么. SSM框架当下比较流行,我也是用这个框架来作为记录,尝试详细地记录下每一个步骤,学习,不要怕开头难. 一.创建一个新的Maven项目 1. new -> Maven -> Maven Project 选择webapp工程. 2.maven项目建好以后,工程目录

[iOS]数据库第三方框架FMDB详细讲解

[iOS]数据库第三方框架FMDB详细讲解 初识FMDB iOS中原生的SQLite API在进行数据存储的时候,需要使用C语言中的函数,操作比较麻烦.于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.PlausibleDatabase.sqlitepersistentobjects等. FMDB是一款简洁.易用的封装库.因此,在这里推荐使用第三方框架FMDB,它是对libsqlite3框架的封装,用起来的步骤与SQLite使用类似,并且它对于多线程的并发操作进行了处理,所以