1.先收集相应的关于坏快的信息,从AlertSID.log文件或者从trace文件中查找,找到例如以下的一些信息:
ORA-01578: ORACLE data block corrupted (file # 4, block # 870212)
file#(RFN) block#
ORA-01110: 数据文件 13: ’D:\ORACLE\ORADATA\SERVER\CWMLITE01.DBF’
file# (AFN) block#
ORA-00600: internal error code, arguments: [kdsgrp1], [], [], [], [], [], [],[], [], [], [], []
file# (AFN) block#
其中RFN表示的是relative_fno
AFN表示的是file_id
(这里注意RFN和AFN的区别:绝对数据文件号(Absolute File# AFN)和相对数据文件号(Relative File# RFN)。AFN是数据文件在整个系统范围内的编号,而RFN是数据文件在表空间范围内的编号。两个文件可能有相同的RFN,但是不会有相同的AFN)
select FILE_NAME, TABLESPACE_NAME, FILE_ID “AFN”, RELATIVE_FNO “RFN”
from DBA_DATA_FILES;
也可以通过dbv或者检查trace文件发现文件号和块号。
2.确定存在坏块的对象是什么:
select *
from DBA_EXTENTS
where FILE_ID = &AFN
and &BL between BLOCK_ID and BLOCK_ID + BLOCKS - 1;
通过上面这个查询语句就可以查出当前存在坏块的对象是什么,是什么类型的对象。需要注意的是如果是temp文件中出现坏块,是没有记录返回的。
3.如果查询出来的坏块处在是索引上,直接rebuild索引即可。
4.如果是数据文件,分两种情况:
1.物理坏块&处于archive模式,并且有有效的全备份和这个备份以后的所有归档,直接使用rman的blockrecover。 (数据文件头block 1不能恢复,只能通过restore、 recover恢复)
RMAM> blockrecover datafile <datafile> block <block number>;
2.逻辑坏块&处于archive模式,并且有有效的备份,使用rman的restore、recover恢复。
RMAN> restore datafile
RMAN> recover datafile
3.处于未archive模式或者处于archive模式,但是没有备份。
1.使用dbms_repair.skip_corrupt_blocks包
exec dbms_repair.skip_corrupt_blocks(’<user>’,’<table>’);
2.使用exp/expdp导出后重建表,imp/impdp导入。
1)exp设置如下内部事件10231,使exp跳过坏块。
alter system set events=’10231 trace name context forever,level 10’;
2)expdp导出会默认跳过坏块,比较方便。