Rman-坏块解决方案

1. 数据块/文件损坏快速处理预案

1.1 坏块问题


【故障现象】

session报错异常退出,alert和trace报错显示存在block corruption:

ORA-01578: ORACLE data block corrupted (file # 7, block # 3)

ORA-01110: data file 7: '/oracle/oradata/trgt/tools01.dbf'

ORA-01578: ORACLE data block corrupted (file # 2, block # 235)

ORA-01110: data file 2: '/oracle/oradata/trgt/undotbs01.dbf'

【可能故障原因】

物理磁盘损坏

 逻辑错误

a) 启用归档备份

【应急措施】

1. 一般来说,在启用归档的情况下,大部分block级别的corruption都可以通过block recover进行恢复,并不一定需要进行数据库整库恢复;

2. 出现报错信息后,建议对数据文件先进行backup validate检查,将在v$database_block_corruption视图中显示检查到的所有坏块信息;

3. 使用block recover命令对坏块进行单独或全部修复

发现坏块

SQL> select count(*) from scott.tb_tmp;  

select count(*) from scott.tb_tmp  

*  

ERROR at line 1:  

ORA-01578: ORACLE data block corrupted (file # 6, block # 133)  

ORA-01110: data file 6: '/u02/database/usbo/oradata/tbs_tmp.dbf'  

 

执行backup validate检查数据文件

RMAN> backup validate datafile 6;

 

时间允许情况下,建议对全库进行检查

RMAN> backup validate database;

 

检查validate结果

SQL> select * from v$database_block_corruption;  

  

     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO  

---------- ---------- ---------- ------------------ ---------  

         6        153          1                  0 CORRUPT  

         6        143          1                  0 CORRUPT  

         6        133          1                  0 CORRUPT  

 

使用block recover进行修复

RMAN> blockrecover datafile 6 block 133;  -- 单块修复

RMAN> blockrecover corruption list;  -- 对视图中所有坏块修复

b) 未启用归档备份

 

【应急措施】

1. 如果数据库没有启用归档和备份,意味这坏块无法进行修复;

2. 检查坏块所在对象,如果是索引对象则可以进行删除重建,如果是表对象并且存在日常备份,考虑进行导入恢复;

3. 如果坏块发生在表对象上并且没有任何备份,意味着该部分数据将丢失,考虑能否通过业务恢复;

4. 如果无法通过业务恢复,可将该部分数据丢弃,将剩余数据重建一张新表使用。

发现坏块

SQL> select count(*) from scott.tb_tmp;  

select count(*) from scott.tb_tmp  

*  

ERROR at line 1:  

ORA-01578: ORACLE data block corrupted (file # 6, block # 133)  

ORA-01110: data file 6: '/u02/database/usbo/oradata/tbs_tmp.dbf'  

 

执行backup validate检查数据文件

RMAN> backup validate datafile 6;

 

时间允许情况下,建议对全库进行检查

RMAN> backup validate database;

 

检查validate结果

SQL> select * from v$database_block_corruption;  

  

     FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO  

---------- ---------- ---------- ------------------ ---------  

         6        153          1                  0 CORRUPT  

         6        143          1                  0 CORRUPT  

         6        133          1                  0 CORRUPT  

 

检查坏块所在对象

SELECT tablespace_name,  

       segment_type,  

       owner,  

       segment_name,  

       partition_name  

  FROM dba_extents  

 WHERE file_id = &file_id AND &block_id BETWEEN block_id AND block_id + blocks - 1;

 

l 如果坏块所在对象为索引,直接进行删除重建可以解决;

l 如果坏块所在对象为表,检查能否通过日常导出备份或业务恢复。

 

标记和跳过坏块

 

a) 新建repair table

BEGIN
DBMS_REPAIR.ADMIN_TABLES (
TABLE_NAME => 'REPAIR_TABLE',
TABLE_TYPE => dbms_repair.repair_table,
ACTION => dbms_repair.create_action,
TABLESPACE => '&TABLESPACE_NAME');
END;

 

b) 检查坏块并记录到repair table

set serveroutput on
DECLARE num_corrupt INT;
BEGIN
num_corrupt := 0;
DBMS_REPAIR.CHECK_OBJECT (
SCHEMA_NAME => '&OWNER',
OBJECT_NAME => '&TABLE',
partition_name => '&PARTITION_NAME',
REPAIR_TABLE_NAME => 'REPAIR_TABLE',
corrupt_count => num_corrupt);
DBMS_OUTPUT.PUT_LINE('number corrupt: ' || TO_CHAR (num_corrupt));
END; 

 

Select * from REPAIR_TABLE;

 

 

c) 标记坏块并设置为查询跳过

DECLARE num_fix INT;
BEGIN
num_fix := 0;
DBMS_REPAIR.FIX_CORRUPT_BLOCKS (
SCHEMA_NAME => '&OWNER',
OBJECT_NAME=> '&TABLE',
partition_name => '&PARTITION_NAME',
OBJECT_TYPE => dbms_repair.table_object,
REPAIR_TABLE_NAME => 'REPAIR_TABLE',
FIX_COUNT=> num_fix);
DBMS_OUTPUT.PUT_LINE('num fix: ' || to_char(num_fix));
END;

BEGIN
DBMS_REPAIR.SKIP_CORRUPT_BLOCKS (
SCHEMA_NAME => '&OWNER',
OBJECT_NAME => '&TABLE',
OBJECT_TYPE => dbms_repair.table_object,
FLAGS => dbms_repair.skip_flag);
END;
/

 

d) CTAS重建新表

 



猜你喜欢

转载自blog.csdn.net/qq_34556414/article/details/80662432