Oracle数据块损坏

Oracle 数据库运行过程中由于硬件故障或操作系统故障导致导致Oracle无法以Oracle格式来识别或所包含的内容即为出现数据块损坏故障,这个坏块可以分为介质损坏以及逻辑损坏。

是一个运行于操作系统提示符下的外部程序,用于验证数据文件,检查块的一致性错误

仅仅针对数据文件,能够校验open阶段的数据文件以及shutdown状态下的数据文件

可以验证复制的数据文件,也可以验证备份的镜像副本

不支持联机日志文件,控制文件,归档日志,RMAN备份集验证

被验证的文件可以位于文件系统,ASM磁盘或原始设备

在Unix系统中位于:$ORACLE_HOME/bin/dbv

在Windows系统中位于:%ORACLE_HOME%/bin/dbv.exe

对于DBVERIFY工具,高版本可以自动识别低版本数据库,比如11g的dbv访问9i的数据库,但是低版本的dbv访问高版本会报错

1
dbv file=sysaux01.dbf

校验并查看结果

视图v$database_block_corruption将列出损坏的坏块所在的文件位置,损坏块的起始位置,损坏快的大小以及损坏类型如果上述视图中发现了坏块,则可以通过SQL查询获得坏块所影响的范围,以及确定坏块所影响的是索引段还是UNDO段

1
2
RMAN> validate datafile 54;
SQL> select * from v$database_block_corruption;
1
2
RMAN> CONFIGURE DEVICE TYPE DISK PARALLELISM 4 BACKUP TYPE TO BACKUPSET;
RMAN> backup validate check logical database;

查看坏块校验结果

1
SQL> select * from v$database_block_corruption;

查看坏块对应的表空间及SEGMENT信息

1
2
3
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报出的坏块出现的文件号和块号)

https://img.bwcxtech.com/img/202209201343319.png

对于坏块处于索引类型,直接重建索引即可

对索引需要用ONLINE,不会从旧索引段中构建新索引,可以从表中读取数据。 删除索引,再重建也可以,可以提前用dbms_metadata.get_ddl获取创建索引语句。

1
2
SQL> ALTER INDEX "SYS"."WRH$_SEG_STAT_PK" REBUILD ONLINE;
SQL> ALTER INDEX "SYS"."WRH$_SQL_PLAN_PK" REBUILD ONLINE; 

如果是分区索引则用:ALTER INDEX "用户名"."表名" REBUILD PARTITION "分区名";

1
SQL> ALTER INDEX "SYS"."WRH$_SEG_STAT_PK" REBUILD PARTITION "WRH$_SEG_STAT_MXDB_MXSN";

获取分区名

1
SQL> select Index_owner,Index_name,partition_name from dba_ind_partitions where index_name = 'WRH$_SEG_STAT_PK';

获取重建语句

1
SQL> select dbms_metadata.get_ddl('INDEX', 'WRH$_SEG_STAT_PK','SYS') FROM dual;

重建索引后,检查坏块

1
2
RMAN> backup validate check logical datafile 2;
SQL> select * from v$database_block_corruption;

若有有效的rman备份则恢复语句如下:

1
2
RMAN> recover datafile 2 block 19846;
RMAN> recover corruption list; # validate 检测后可用该语句进行恢复

若仅有数据泵备份,则从数据泵恢复该表数据到备份的状态。

1
2
impdp directory=dump dumpfile=back.dump SCHEMAS=APP include=table:"\=\'T_OBJ\'"
impdp directory=dump dumpfile=back.dump tables=APP.T_OBJ

无备份,屏蔽掉坏块,拯救部分数据。

启用10231内部事件

1
SQL> alter system set events='10231 trace name context forever,level 10';

关闭10231内部事件

1
SQL> alter system set events='10231 trace name context off’;