坏块处理

背景:

数据库异常宕机,检查日志后发现报错ora-00600,仔细检查日志后发现存在坏块

有报错对象的object id,大佬发现后推断出是逻辑坏块,进行重建后解决

对大佬的操作过程进行模拟记录并补充



1)模拟操作,已确认为逻辑坏块


1.首先日志中拿到object号


查询对应的对象类型信息


select owner,object_name,object_type from dba_objects where object_id=41;


OWNER                OBJECT_NAME                                                                                           OBJECT_TYPE

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

SYS                  I_IND1                                                                                                INDEX


2.查询为索引,进行创建语句的查看

select dbms_metadata.get_ddl('INDEX','I_IND1') from dual;



DBMS_METADATA.GET_DDL('INDEX','I_IND1')

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


  CREATE UNIQUE INDEX "SYS"."I_IND1" ON "SYS"."IND$" ("OBJ#")

  PCTFREE 10 INI

 

3.重建对象 

drop index XXX
执行重建ddl

 

2)补充坏块情况

v$DATABASE_BLOCK_CORRUPTION中的CORRUPTION_TYPE有以下几种情况:


 1、ALL ZERO


 ------磁盘上的块标头仅包含零。如果该块从未填充,并且位于Oracle7文件中,则该块可能有效。对于空块,缓冲区将重新格式化为Oracle8标准。


 2、FRACTURED


 ------块头看起来合理,但块的前面和后面是不同的版本。


 3、CHECKSUM


 ------可选检查值显示块不是自一致的。不可能确切地确定检查值失败的原因,但是它可能失败,因为块中间的扇区来自不同的版本。


 4、CORRUPT


 ------锁被错误识别或不是数据块(例如,数据块地址丢失)。


 5、LOGICAL


 ------块在逻辑上已损坏。


 6、NOLOGGING


 ------块没有重做日志项(例如,主数据库上的NOLOGGING操作可能会在物理备用数据库上引入这种类型的损坏)


若有坏块id,可查询

SELECT tablespace_name, segment_type, owner, segment_name, partition_name  FROM dba_extents WHERE file_id = and between block_id AND block_id + blocks - 1;

 查询坏块

select * from v$database_block_corruption;

一般坏块原因分为物理和逻辑坏块,物理一般为系统原因,io问题或操作系统故障问题,逻辑原因一般为数据库软件原因,如系统bug,头文件损坏等。

一般处理方法

1.查询出坏块号进行备份恢复,

restore datafile file#;
recover datafile file#;

2重建表处理方法

设置事件,跳过坏块


ALTER SYSTEM SET EVENTS '10231 trace name context forever,level 10';

读出表内容,准备导出

create table recover_data_temp as select * from test;

删除表,进行重建

drop table test;

 exp "'sys/oracle@pdb as sysdba'" file=test.dmp tables=test;

 imp "'sys/oracle@pdb as sysdba'" file=test.dmp tables=test;

取消事件

alter system set events='10231 trace name context off';