Oracle数据恢复:Oracle RAC系统Redo/Undo损坏恢复

昨天,一个客户的数据库系统出现故障,RAC无法启动,大量的错误信息,经过分析检查,最后我们通过强制手段打开数据库,帮助用户挽回了数据损失。

故障的起因应该是主机和存储之间出现连接故障,message信息里可以看到大量如下提示:

Jun  1 19:57:18 Oracle-02 kernel: end_request: I/O error, dev sdb, sector 12931135
Jun  1 19:57:18 Oracle-02 kernel: sd 6:0:0:1: Device not ready: <6>: Current: sense key: Not Ready
Jun  1 19:57:18 Oracle-02 kernel:     Add. Sense: Logical unit not accessible, asymmetric access state transition
Jun  1 19:57:18 Oracle-02 kernel:
Jun  1 19:57:18 Oracle-02 kernel: end_request: I/O error, dev sdb, sector 12931647
Jun  1 19:57:18 Oracle-02 kernel: sd 6:0:0:1: Device not ready: <6>: Current: sense key: Not Ready
Jun  1 19:57:18 Oracle-02 kernel:     Add. Sense: Logical unit not accessible, asymmetric access state transition
Jun  1 19:57:18 Oracle-02 kernel:
Jun  1 19:57:18 Oracle-02 kernel: end_request: I/O error, dev sdb, sector 12932671
Jun  1 19:57:18 Oracle-02 kernel: sd 6:0:0:1: Device not ready: <6>: Current: sense key: Not Ready
Jun  1 19:57:18 Oracle-02 kernel:     Add. Sense: Logical unit not accessible, asymmetric access state transition

一旦出现IO写失败或者写丢失,则数据库将遭受数据损失,一旦UNDO和REDO损坏,数据库就将会无法启动。

在数据库的告警日志层面,首先出现的错误是如下类型:

WARNING: Read Failed. group:3 disk:0 AU:102 offset:16384 size:16384
WARNING: failed to read mirror side 1 of virtual extent 0 logical extent 0 of file 256 in group [3.3870646521] from disk REDO1  allocation unit 102 reason error; if possible,will try another mirror side
WARNING: Read Failed. group:3 disk:0 AU:102 offset:16384 size:16384
WARNING: failed to read mirror side 1 of virtual extent 0 logical extent 0 of file 256 in group [3.3870646521] from disk REDO1  allocation unit 102 reason error; if possible,will try another mirror side

这些错误首先提示REDO写操作失败,读写AU单位失败,这类错误信息教Oracle 11gR2之前详细了很多,精确到了AU单位及Offset。

在启动过程中出现了ORA-00600错误:

ARC0: STARTING ARCH PROCESSES COMPLETE
Redo thread 2 internally disabled at seq 1 (CKPT)
ARC2: Archiving disabled thread 2 sequence 1
Archived Log entry 785 added for thread 2 sequence 1 ID 0x0 dest 1:
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.
Errors in file /oracle/diag/rdbms/spsp/SPSP1/trace/SPSP1_ora_19044.trc:
ORA-00600: internal error code, arguments: [2662], [0], [7291890], [0], [7314785], [12583040], [], [], [], [], [], []
Errors in file /oracle/diag/rdbms/spsp/SPSP1/trace/SPSP1_ora_19044.trc:
ORA-00600: internal error code, arguments: [2662], [0], [7291890], [0], [7314785], [12583040], [], [], [], [], [], []

Errors in file /oracle/diag/rdbms/spsp/SPSP2/trace/SPSP2_smon_14335.trc  (incident=291384):
ORA-00600: internal error code, arguments: [4194], [], [], [], [], [], [], [], [], [], [], []
Incident details in: /oracle/diag/rdbms/spsp/SPSP2/incident/incdir_291384/SPSP2_smon_14335_i291384.trc
Use ADRCI or Support Workbench to package the incident.
See Note 411.1 at My Oracle Support for error and packaging details.

注意Oracle 11gR2的提示,非常详尽,居然提示你通过My Oracle Support去参考 Note 411.1 学习ADRCI知识。

ORA-600的 4193 和 4194 错误,可以通过重建回滚表空间解决。
此处需要提醒的是,Oracle 11g的缺省UNDO段命名,增加了一个Unix Time的时间戳在回滚段名称里,如下所示:

SQL> select * from v$rollname;

USN NAME
———- ——————————
0 SYSTEM
31 _SYSSMU31_1012201531$
32 _SYSSMU32_3505455792$
33 _SYSSMU33_760762808$
34 _SYSSMU34_2022544229$
35 _SYSSMU35_774751923$
36 _SYSSMU36_3132287946$
37 _SYSSMU37_1634453262$
38 _SYSSMU38_1341527290$
39 _SYSSMU39_2970077311$
40 _SYSSMU40_1403026629$

在设置初始化参数时大致设置如下:

  _allow_resetlogs_corruption= TRUE
_offline_rollback_segments= “_SYSSMU11_1202330240$”
_offline_rollback_segments= “_SYSSMU12_1617713323$”
_offline_rollback_segments= “_SYSSMU13_1359816937$”
_offline_rollback_segments= “_SYSSMU14_2078039711$”
_offline_rollback_segments= “_SYSSMU15_1538259293$”
_offline_rollback_segments= “_SYSSMU16_3126366281$”
_offline_rollback_segments= “_SYSSMU17_2553547900$”
_offline_rollback_segments= “_SYSSMU18_1481844821$”
_offline_rollback_segments= “_SYSSMU19_135756661$”
_offline_rollback_segments= “_SYSSMU20_2322289537$”
_corrupted_rollback_segments= “_SYSSMU11_1202330240$”
_corrupted_rollback_segments= “_SYSSMU12_1617713323$”
_corrupted_rollback_segments= “_SYSSMU13_1359816937$”
_corrupted_rollback_segments= “_SYSSMU14_2078039711$”
_corrupted_rollback_segments= “_SYSSMU15_1538259293$”
_corrupted_rollback_segments= “_SYSSMU16_3126366281$”
_corrupted_rollback_segments= “_SYSSMU17_2553547900$”
_corrupted_rollback_segments= “_SYSSMU18_1481844821$”
_corrupted_rollback_segments= “_SYSSMU19_135756661$”
_corrupted_rollback_segments= “_SYSSMU20_2322289537$”

屏蔽了事务的回滚与重做之后,数据库被成功打开。

SQL> select * from v$version;

BANNER
——————————————————————————–
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 – 64bit Production
PL/SQL Release 11.2.0.2.0 – Production
CORE    11.2.0.2.0      Production
TNS for Linux: Version 11.2.0.2.0 – Production
NLSRTL Version 11.2.0.2.0 – Production

数据库风险随时可能发生,备份必不可少啊

ORA-00600 kclchkblk_4 错误恢复案例一则

最近客户在恢复数据库时遇到了ORA-600 kclchkblk_4错误,这个错误在MOS上有官方的解释和解决方案。

在以下错误提示下:

Errors in file /u01/app/oracle/admin/orcl/bdump/orcl_smon_7493.trc:
ORA-600: internal error code, arguments: [kclchkblk_4], [1904],[18446744073431179384], [1904],18446744073403569507], [], [], []

Starting background process QMNC
QMNC started with pid=24, OS id=8329

Errors in file /u01/app/oracle/admin/orcl/bdump/orcl_smon_7493.trc:
ORA-600: internal error code, arguments: [2662], [1904], [3988985522],[1904], [4016595064], [8388610], [], []

Errors in file /u01/app/oracle/admin/orcl/bdump/orcl_smon_7493.trc:
ORA-600: internal error code, arguments: [2662], [1904], [3988985525],[1904], [4016595064], [8388610], [], []
SMON: terminating instance due to error 474
Instance terminated by SMON, pid = 7493

其问题,可能是由于临时表空间的SCN问题导致的,可以尝试删除所有的临时文件,启动数据库,通常可能正常启动。
可能的采取步骤是,在Mount状态下确定并删除临时文件:

    SQL>select file_name, file_id from dba_temp_files;
SQL>alter database tempfile_name drop;
SQL>alter tablespace add tempfile size N;

如果数据库能够成功启动,可以重建临时文件。

顺便引用一下ITPUB上一个朋友的帖子供参考: http://www.itpub.net/thread-1404451-1-1.html

问题描述:
服务器突然故障死机,导致数据库无法驱动,redo的CURRENT组的损坏。oracle 10g rac环境,asm磁盘组,redhat linux系统。每个组一个成员这个是组被破坏无法修复的关键。
没有归档,没有备份。使用ASM无法将数据文件冷备份出来。

ORA-00368: checksum error in redo log block
ORA-00353: log corruption near block 254606 change 12131176305969 time 03/08/2011 01:03:00
ORA-00312: online log 2 thread 1: ‘+DG1/police/onlinelog/group_2.258.657430669’

查看日志组文件信息,报错的日志组为CURRENT模式。

SQL> select group#,sequence#,archived,status from v$log;

GROUP#  SEQUENCE# ARC STATUS
———- ———- — —————-
1      17495 NO  INACTIVE
2      17496 NO  CURRENT
3      17365 NO  INACTIVE
4      17366 NO  CURRENT

组成员只有一个。

SQL>

Group   Instance             Member             STATUS             Size(MB)
———- ———- —————————— —————- ———-
1          1 +DG1/police/onlinelog/group_1. INACTIVE                500
257.657430665

2          1 +DG1/police/onlinelog/group_2. CURRENT                 500
258.657430669

3          2 +DG1/police/onlinelog/group_3. INACTIVE                500
265.657431819

4          2 +DG1/police/onlinelog/group_4. CURRENT                 500
266.657431825

无法使用clear命令清楚redo的信息

SQL> alter database clear unarchived logfile group 2
2  ;
alter database clear unarchived logfile group 2
*
ERROR at line 1:
ORA-01624: log 2 needed for crash recovery of instance police1 (thread 1)
ORA-00312: online log 2 thread 1: ‘+DG1/police/onlinelog/group_2.258.657430669’

SQL> alter database clear logfile group 2;
alter database clear logfile group 2
*
ERROR at line 1:
ORA-01624: log 2 needed for crash recovery of instance police1 (thread 1)
ORA-00312: online log 2 thread 1: ‘+DG1/police/onlinelog/group_2.258.657430669’

处理步骤

把数据库down掉

   SQL>shutdown immediate

5、在init<sid>.ora中加入如下参数

_allow_resetlogs_corruption=TRUE

6、重新启动数据库,利用until cancel恢复

SQL>recover database until cancel;
Cancel

如果出错,不再理会,发出

SQL>alter database open resetlogs;

如果运气好的话可以正常启动数据库,就可以导出数据了。但是这里有点意外不知道是点背还是rac环境的恢复比较特殊。在alert.log中有如下报错:

Errors in file /u01/app/oracle/admin/police/bdump/police2_j003_17720.trc:
ORA-00600: internal error code, arguments: [4194], [9], [8], [], [], [], [], []
Wed Mar  9 18:08:06 2011
Errors in file /u01/app/oracle/admin/police/bdump/police2_j004_17722.trc:
ORA-00600: internal error code, arguments: [4193], [55749], [55753], [], [], [], [], []
Wed Mar  9 18:08:08 2011
Errors in file /u01/app/oracle/admin/police/bdump/police2_mmon_11328.trc:
ORA-00600: internal error code, arguments: [4194], [12], [17], [], [], [], [], []
Wed Mar  9 18:08:08 2011
Errors in file /u01/app/oracle/admin/police/bdump/police2_j002_17718.trc:
ORA-00600: internal error code, arguments: [kcbz_check_objd_typ_3], [0], [0], [1], [], [], [], []

能后我就重复启动数据库这个错误就过去了,网上有一篇文档是这么说的,真的可以过去,不过我是将两个节点都同时启动的时候过去的,但是在开始出现如下错误:
ORA-600[KCLCHKBLK_4]【2824】,但是没有出现ORA-600[2662]的报错,不知道为什么,有人说是temp文件不一致造成,但是别人都有2662的报错我这里没有,不管了先将temp删了在说。

能后速度将temp删除,能后发现问题依旧。当时我就很失望了,情绪低落。这个报错在网上的解决办法只有这一个。也没有什么人有更好的建议。
ORA-00600: internal error code, arguments: [kclchkblk_4], [2824], [18446744071603238605], [2824], [18446744071593491338], [], [], []
Wed Mar  9 14:29:55 2011
Errors in file /u01/app/oracle/admin/police/udump/police1_ora_27660.trc:
ORA-00600: internal error code, arguments: [kclchkblk_4], [2824], [18446744071603238605], [2824], [18446744071593491338], [], [], []
Wed Mar  9 14:29:55 2011
Error 600 happened during db open, shutting down database
USER: terminating instance due to error 600

但是仔细观察后我发现18446744071593491338这个数据有问题,它在我每次重新启动数据库的时候会和前面的数值有所改变18446744071593491338,我的目标就是将
这个数值尽量的缩小和18446744071603238605的值,重复几遍后发现使用srvctl start database -d sid数据库会自动重启多次,我就不停地启动关闭。有希望了两个者还是相差太大,
这一步我们在这里卡了很久。这里有一个scn的问题,我这里碰到的是后面的比前面的低,所以adjust_scn没有效果。
无赖我将_allow_resetlogs_corruption=TRUE增加到spfile中让数据库同时启动。结果发现错误改变了,后来想想估计是要将参数添加到spfile中同时启动数据库才有效果,因为我单独启动数据库的时候效果不大。

Errors in file /u01/app/oracle/admin/police/bdump/police2_smon_11322.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
Wed Mar  9 18:08:35 2011
ORACLE Instance police2 (pid = 16) – Error 600 encountered while recovering transaction (9, 46).
Wed Mar  9 18:08:35 2011
Errors in file /u01/app/oracle/admin/police/bdump/police2_smon_11322.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
Wed Mar  9 18:08:35 2011
Trace dumping is performing id=[cdmp_20110309180835]
Wed Mar  9 18:08:37 2011
Errors in file /u01/app/oracle/admin/police/bdump/police2_smon_11322.trc:
ORA-00600: internal error code, arguments: [4137], [], [], [], [], [], [], []
Errors in file /u01/app/oracle/admin/police/bdump/police2_p007_19333.trc:
ORA-00600: internal error code, arguments: [4198], [9], [], [], [], [], [], []

出现了这些报错,现在好了,4137,4138 ,4139不都是undo的报错吧,
新建立两个undo,修改spfile使用新的undo启动,删除旧的undo。
添加spfile参数

_allow_resetlogs_corruption”=true ”
_allow_terminal_recovery_corruption”=true
_corrupted_rollback_segments =’_SYSSMU1$’,’_SYSSMU2$’,’_SYSSMU3$’

如果不能确定多少个,但是我在删除UNDO的时候提示_SYSSMU2无法删除,我还是坚持加到了20个,后来我查了一下一共有400多个还好没有每个都坏掉。
修改undo_management 这个参数
把参数文件中的undo_management 改为MANUAL

SQL> create undo tablespace undotbs3 datafile ‘/opt/oracle/oradata/conner/undotbs3.dbf’ size 10M;
Tablespace created.
SQL> alter system set undo_tablespace=undotbs1 scope=spfile sid=’sid’;
System altered.
SQL> drop tablespace undotbs2;
Tablespace dropped.

将两个节点的undo都替换后发现数据库可以起来了,但还是有报错,

Errors in file /u01/app/oracle/admin/police/bdump/police2_j000_7977.trc:
ORA-00600: internal error code, arguments: [kcbz_check_objd_typ_3], [0], [0], [1], [], [], [], []
Wed Mar  9 23:56:10 2011

但还好可以exp数据了。

导出数据后,删除数据库,删除asm,
关闭第二台的asm实例,
登入第一台asm

SQL> select name from v$asm_diskgroup;
NAME
——————————
DG1
SQL> drop diskgroup DG1 including contents;       –>删除磁盘组
SQL>SHUTDOWN IMMEDIATE

最后
crs_unregister ora.node1.ASM1.asm
crs_unregister ora.node1.ASM1.asm(后来极度后悔,应该在unregister前备份一下就好了)
在dbs和admin下删除asm相关文档
修改/etc/oratab文件将asm的注释。
dbca重新建立asm磁盘发现asm实例无法启动晕倒。好像是出现prks-1011,和ora-0210的报错
使用srvctl add asm -n node1 -i +ASM1 -o $ORACLE_HOME -p init+ASM1.ora
提示ora.node1.ASM1.asm服务已经存在了,但是crs_stat -t查看又没有ora.node1.ASM1.asm服务。
于是我使用crs_register ora.node1.ASM1.asm的时候提示找不到 ora.node1.ASM1.asm.cap的文件(这里折腾了一段时间)
没法我从别的rac上使用crs_stat -p ora.node1.ASM1.asm > ora.node1.ASM1.asm.cap导出了一份拷贝到提示的目录下,并且修改了文件中的主机信息等。
在使用crs_register ora.node1.ASM1.asm就注册成功了。其实 ora.node1.ASM1.asm.cap这个文件的东西和 ora.node1.lsnr的文件内容一样。就是有些东西自己动手修改一下就可以替代了。
重新建库导入文件
艰苦的数据恢复终于完成了。