Oracle数据块损坏
Oracle 数据库运行过程中由于硬件故障或操作系统故障导致导致Oracle无法以Oracle格式来识别或所包含的内容即为出现数据块损坏故障,这个坏块可以分为介质损坏以及逻辑损坏。
1 检验坏块
1.1 使用DBVERIFY工具检验坏块
是一个运行于操作系统提示符下的外部程序,用于验证数据文件,检查块的一致性错误
仅仅针对数据文件,能够校验open阶段的数据文件以及shutdown状态下的数据文件
可以验证复制的数据文件,也可以验证备份的镜像副本
不支持联机日志文件,控制文件,归档日志,RMAN备份集验证
被验证的文件可以位于文件系统,ASM磁盘或原始设备
在Unix系统中位于:$ORACLE_HOME/bin/dbv
在Windows系统中位于:%ORACLE_HOME%/bin/dbv.exe
对于DBVERIFY工具,高版本可以自动识别低版本数据库,比如11g的dbv访问9i的数据库,但是低版本的dbv访问高版本会报错
dbv file=sysaux01.dbf
校验并查看结果
视图v$database_block_corruption
将列出损坏的坏块所在的文件位置,损坏块的起始位置,损坏快的大小以及损坏类型如果上述视图中发现了坏块,则可以通过SQL查询获得坏块所影响的范围,以及确定坏块所影响的是索引段还是UNDO段
RMAN> validate datafile 54;
SQL> select * from v$database_block_corruption;
1.2 使用RMAN检验坏块
RMAN> CONFIGURE DEVICE TYPE DISK PARALLELISM 4 BACKUP TYPE TO BACKUPSET;
RMAN> backup validate check logical database;
查看坏块校验结果
SQL> select * from v$database_block_corruption;
查看坏块对应的表空间及SEGMENT信息
SQL> select name from v$dbfile where file#=2;
SQL> select * from dba_extents where file_id=<F> and <B> between block_id and block_id + blocks - 1;
(
<F>
和<B>
分别是ORA-01578报出的坏块出现的文件号和块号)
2 修复坏块
对于坏块处于索引类型,直接重建索引即可
对索引需要用ONLINE,不会从旧索引段中构建新索引,可以从表中读取数据。
删除索引,再重建也可以,可以提前用dbms_metadata.get_ddl
获取创建索引语句。
SQL> ALTER INDEX "SYS"."WRH$_SEG_STAT_PK" REBUILD ONLINE;
SQL> ALTER INDEX "SYS"."WRH$_SQL_PLAN_PK" REBUILD ONLINE;
如果是分区索引则用:ALTER INDEX "用户名"."表名" REBUILD PARTITION "分区名";
SQL> ALTER INDEX "SYS"."WRH$_SEG_STAT_PK" REBUILD PARTITION "WRH$_SEG_STAT_MXDB_MXSN";
获取分区名
SQL> select Index_owner,Index_name,partition_name from dba_ind_partitions where index_name = 'WRH$_SEG_STAT_PK';
获取重建语句
SQL> select dbms_metadata.get_ddl('INDEX', 'WRH$_SEG_STAT_PK','SYS') FROM dual;
重建索引后,检查坏块
RMAN> backup validate check logical datafile 2;
SQL> select * from v$database_block_corruption;
若有有效的rman备份则恢复语句如下:
RMAN> recover datafile 2 block 19846;
RMAN> recover corruption list; # validate 检测后可用该语句进行恢复
若仅有数据泵备份,则从数据泵恢复该表数据到备份的状态。
impdp directory=dump dumpfile=back.dump SCHEMAS=APP include=table:"\=\'T_OBJ\'"
impdp directory=dump dumpfile=back.dump tables=APP.T_OBJ
无备份,屏蔽掉坏块,拯救部分数据。
启用10231内部事件
SQL> alter system set events='10231 trace name context forever,level 10';
关闭10231内部事件
SQL> alter system set events='10231 trace name context off';