一次ORA-00600[3020]和ORA-00600[2663]的数据恢复

今天接到电话,一个客户发生了断电,数据库无法打开,100多G的数据,很着急.我叫他们先给我传日志,从日志上来看,客户已经做了recover操作,但是recover操作失败,报ORA-01196和ORA-01110.system这个文件需要更多的恢复来保证一致性.错误日志如下:

AUDIT_TRAIL initialization parameter is changed to OS, as DB is NOT compatible for database opened with read-only access
Errors in file f:\app\nb\diag\rdbms\snsoftjknew\snsoftjknew\trace\snsoftjknew_ora_4856.trc:
ORA-16004: 备份数据库需要恢复
ORA-01194: 文件 1 需要更多的恢复来保持一致性
ORA-01110: 数据文件 1: 'F:\APP\NB\ORADATA\SNSOFTJKNEW\SYSTEM01.DBF'
ORA-16004 signalled during: alter database open read only...

这个客户没有开归档也没有做备份,我过去后想尝试用RMAN来进行恢复,结果报ORA-00600[3020]错误,错误输出如下:

RMAN> recover database;
启动 recover 于 09-4月 -12
使用目标数据库控制文件替代恢复目录
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: SID=114 设备类型=DISK
正在开始介质的恢复
线程 1 序列 8860 的归档日志已作为文件 F:\APP\NB\ORADATA\SNSOFTJKNEW\REDO01.LOG
存在于磁盘上
线程 1 序列 8861 的归档日志已作为文件 F:\APP\NB\ORADATA\SNSOFTJKNEW\REDO02.LOG
存在于磁盘上
线程 1 序列 8862 的归档日志已作为文件 F:\APP\NB\ORADATA\SNSOFTJKNEW\REDO03.LOG
存在于磁盘上
归档日志文件名=F:\APP\NB\ORADATA\SNSOFTJKNEW\REDO01.LOG 线程=1 序列=8860
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: recover 命令 (在 04/09/2012 17:34:52 上) 失败
RMAN-11003: 在分析/执行 SQL 语句期间失败: alter database recover logfile 'F:\APP
\NB\ORADATA\SNSOFTJKNEW\REDO01.LOG'
ORA-00600: internal error code, arguments: [3020], [14], [3489040], [62209296],
[], [], [], [], [], [], [], []
ORA-10567: Redo is inconsistent with data block (file# 14, block# 3489040, file
offset is 2812411904 bytes)
ORA-10564: tablespace FININDX_TBS
ORA-01110: data file 14: 'F:\APP\NB\ORADATA\SNSOFTJKNEW\FININDX2'
ORA-10561: block type 'TRANSACTION MANAGED INDEX BLOCK', data object# 75622

这个错误是说磁盘的块被标记成了坏块,因为redo log中没有与之对应的一致性信息.这里我们可以通过运行recover database allow 1 corruption来尝试recover,每次都跳过1个坏块来恢复,重复运行该命令.

RMAN> recover database allow 1 corruption;
启动 recover 于 09-4月 -12
使用通道 ORA_DISK_1
正在开始介质的恢复
线程 1 序列 8860 的归档日志已作为文件 F:\APP\NB\ORADATA\SNSOFTJKNEW\REDO01.LOG
存在于磁盘上
线程 1 序列 8861 的归档日志已作为文件 F:\APP\NB\ORADATA\SNSOFTJKNEW\REDO02.LOG
存在于磁盘上
线程 1 序列 8862 的归档日志已作为文件 F:\APP\NB\ORADATA\SNSOFTJKNEW\REDO03.LOG
存在于磁盘上
归档日志文件名=F:\APP\NB\ORADATA\SNSOFTJKNEW\REDO01.LOG 线程=1 序列=8860
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: recover 命令 (在 04/09/2012 17:38:56 上) 失败
ORA-00283: recovery session canceled due to errors
RMAN-11003: 在分析/执行 SQL 语句期间失败: alter database recover logfile 'F:\APP
\NB\ORADATA\SNSOFTJKNEW\REDO01.LOG'
ORA-00283: 恢复会话因错误而取消
ORA-00600: 内部错误代码, 参数: [3020], [10], [2391661], [44334701], [], [], [],
[], [], [], [], []
ORA-10567: Redo is inconsistent with data block (file# 10, block# 2391661, file
offset is 2412617728 bytes)
ORA-10564: tablespace FININDX_TBS
ORA-01110: 数据文件 10: 'F:\SNDATA\SNSOFTJKNEW\FININDX_TBS.DBF'
ORA-10561: block type 'TRANSACTION MANAGED INDEX BLOCK', data object# 75618
RMAN>

但是连续几次都是不同坏块错误,可能坏块比较多,可以看到文件10和文件14都有坏块,还好这两个文件都是一个表空间FININDX的,所以我用dbv做了一个检测.检测了一下文件10.如下所示:

C:\Documents and Settings\nb>dbv file=F:\SNDATA\SNSOFTJKNEW\FININDX_TBS.DBF bloksize=8192
DBVERIFY: Release 11.2.0.1.0 - Production on 星期一 4月 9 17:43:12 2012
Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
DBVERIFY - 开始验证: FILE = F:\SNDATA\SNSOFTJKNEW\FININDX_TBS.DBF
页 2520845 流入 - 很可能是介质损坏
Corrupt block relative dba: 0x02a6770d (file 10, block 2520845)
Fractured block found during dbv:
Data in bad block:
 type: 6 format: 2 rdba: 0x02a6770d
 last change scn: 0x0000.03c265c8 seq: 0x2 flg: 0x04
 spare1: 0x0 spare2: 0x0 spare3: 0x0
 consistency value in tail: 0x40050601
 check value in block header: 0x7b95
 computed block checksum: 0x27cf

页 2520853 流入 - 很可能是介质损坏
Corrupt block relative dba: 0x02a67715 (file 10, block 2520853)
Fractured block found during dbv:
Data in bad block:
 type: 6 format: 2 rdba: 0x02a67715
 last change scn: 0x0000.03c24007 seq: 0x1 flg: 0x04
 spare1: 0x0 spare2: 0x0 spare3: 0x0
 consistency value in tail: 0x65d00601
 check value in block header: 0x6610
 computed block checksum: 0x24d5

页 2662653 流入 - 很可能是介质损坏
Corrupt block relative dba: 0x02a8a0fd (file 10, block 2662653)
Fractured block found during dbv:
Data in bad block:
 type: 6 format: 2 rdba: 0x02a8a0fd
 last change scn: 0x0000.03c259a4 seq: 0x2 flg: 0x04
 spare1: 0x0 spare2: 0x0 spare3: 0x0
 consistency value in tail: 0x37000601
 check value in block header: 0xa85f
 computed block checksum: 0x6ca6

页 2763077 流入 - 很可能是介质损坏
Corrupt block relative dba: 0x02aa2945 (file 10, block 2763077)
Fractured block found during dbv:
Data in bad block:
 type: 6 format: 2 rdba: 0x02aa2945
 last change scn: 0x0000.03c256f5 seq: 0x6 flg: 0x04
 spare1: 0x0 spare2: 0x0 spare3: 0x0
 consistency value in tail: 0x36670602
 check value in block header: 0x5b4f
 computed block checksum: 0x6194

DBV-00200: 块 DBA 44736805 已标记为损坏
DBV-00200: 块 DBA 44736981 已标记为损坏

DBVERIFY - 验证完成

检查的页总数: 3815680
处理的页总数 (数据): 0
失败的页总数 (数据): 0
处理的页总数 (索引): 2077479
失败的页总数 (索引): 0
处理的页总数 (其他): 10958
处理的总页数 (段)  : 0
失败的总页数 (段)  : 0
空的页总数: 1727239
标记为损坏的总页数: 6
流入的页总数: 4
加密的总页数        : 0
最高块 SCN            : 63075641 (0.63075641)

这里显示表记为损坏的总页数是6, 我觉得用上述方法太麻烦了,所以我想尝试用_allow_resetlogs_corruption隐含参数跳过一致性检测打开数据库,然后在把有问题的索引表空间干掉就行了.于是我生成了参数文件,并设置了该参数,在打开数据库的时候报另外一个ORA-00600[2663]错误.如下:

SQL> alter database open resetlogs;
alter database open resetlogs
*
第 1 行出现错误:
ORA-01092: ORACLE instance terminated. Disconnection forced
ORA-00600: internal error code, arguments: [2663], [0], [63069867], [0],
[63071833], [], [], [], [], [], [], []
进程 ID: 4956
会话 ID: 66 序列号: 3

对于ORA-00600[2662]和ORA-00600[2663]错误,都是因为SCN号不一致导致的,需要adjust scn操作.

SQL> alter session set events '10015 trace name adjust_scn level 1';

会话已更改。

SQL> alter database open;

数据库已更改。
SQL> select CHECKPOINT_CHANGE#,NAME from v$datafile;

CHECKPOINT_CHANGE# NAME
------------------ ------------------------------------------------------------
          63153217 F:\APP\NB\ORADATA\SNSOFTJKNEW\SYSTEM01.DBF
          63153217 F:\APP\NB\ORADATA\SNSOFTJKNEW\SYSAUX01.DBF
          63153217 F:\APP\NB\ORADATA\SNSOFTJKNEW\UNDOTBS01.DBF
          63153217 F:\APP\NB\ORADATA\SNSOFTJKNEW\USERS01.DBF
          63153217 F:\SNDATA\SNSOFTJKNEW\SYSDATA_TBS.DBF
          63153217 F:\SNDATA\SNSOFTJKNEW\OPTDATA_TBS.DBF
          63153217 F:\SNDATA\SNSOFTJKNEW\FINDATA_TBS.DBF
          63153217 F:\SNDATA\SNSOFTJKNEW\HRDATA_TBS.DBF
          63153217 F:\SNDATA\SNSOFTJKNEW\OPTINDX_TBS.DBF
          63119408 F:\SNDATA\SNSOFTJKNEW\FININDX_TBS.DBF
          63153217 F:\SNDATA\SNSOFTJKNEW\SYSINDX_TBS.DBF
          63153217 F:\SNDATA\SNSOFTJKNEW\HRINDX_TBS.DBF
          63153217 F:\SNDATA\SNSOFTJKNEW\USER_DATA.DBF
          63119408 F:\APP\NB\ORADATA\SNSOFTJKNEW\FININDX2
          63153217 F:\APP\NB\ORADATA\SNSOFTJKNEW\USER_DATA2

已选择15行。

此时我们可以看到就两个文件的SCN号是有问题的,这两个文件都是存放索引的表空间,那么我直接干掉这个表空间就可以了,但是悲剧的事情是该表空间有一些主键,是不能直接drop的,所以我把错误的对象都删掉.然后用expdp把该库数据导出,然后重建了数据库,导入数据,最终解决了这个问题.

分享到: 更多

Post a Comment

Your email is never published nor shared. Required fields are marked *