数据库坏块典型案例拓展
1 、 物理坏块
物理坏块指的是块格式本身已经损坏,块内的数据没有任何意义。物理坏块一般是由于内存问题、 OS 问题、 I/O 子系统问题或硬件引起的,逻辑坏块一般是由 Oracle Bug 等原因引起的。物理块损坏也可以称为介质块损坏( Media Corrupt Block )。物理坏块可以分为以下几类:
(1) 坏头( Bad header ):数据块头( Cache Header )被无效值损坏
(2) 块有裂缝 / 不完整( Fractured/Incompleted Block ):数据块头和块尾不匹配,其 trace 文件内容如下所示:
Corrupt block relative dba: 0x0380e573 (file 14, block 58739)
Fractured block found during buffer read
Data in bad block -
type: 6 format: 2 rdba: 0x0380e573
last change scn: 0x0288.8e5a2f78 seq: 0x1 flg: 0x04
consistency value in tail: 0x00780601
check value in block header: 0x8739, computed block checksum: 0x2f00
spare1: 0x0, spare2: 0x0, spare3: 0x0
***
Reread of rdba: 0x0380e573 (file 14, block 58739) found same corrupted data
(3) 块的块校验和( checksum )无效,其 trace 内容如下所示:
Corrupt block relative dba: 0x0380a58f (file 14, block 42383)
Bad check value found during buffer read
Data in bad block -
type: 6 format: 2 rdba: 0x0380a58f
last change scn: 0x0288.7784c5ee seq: 0x1 flg: 0x06
consistency value in tail: 0xc5ee0601
check value in block header: 0x68a7, computed block checksum: 0x2f00
spare1: 0x0, spare2: 0x0, spare3: 0x0
***
Reread of rdba: 0x0380a58f (file 14, block 42383) found same corrupted data
(4) 块的位置错误( Block Misplaced ):检验和正确,但是正在被读取的数据块的内容属于另外一个块
Corrupt block relative dba: 0x0d805a89 (file 54, block 23177)
Bad header found during buffer read
Data in bad block -
type: 6 format: 2 rdba: 0x0d805b08 ----> Block is different than expected 0x0d805a89
last change scn: 0x0692.86dc08e3 seq: 0x1 flg: 0x04
consistency value in tail: 0x08e30601
check value in block header: 0x2a6e, computed block checksum: 0x0
spare1: 0x0, spare2: 0x0, spare3: 0x0
***
(5) 归零的块( Zeroed out blocks )( Note 1545366.1 )
Corrupt block relative dba: <rdba> (file <file#>, block <block#>)
Completely zero block found during buffer read
Reading datafile 'datafile' for corruption at rdba: <rdba> (file <file#>, block <block#>)
Reread (file <file#>, block <block#>) found same corrupt data (no logical check)
2、 逻辑坏块
逻辑坏块指的是块内的数据在逻辑上存在问题,比如说索引块的索引值没有按顺序排列导致的逻辑坏块。逻辑坏块通常包含一个正确的 checksum 和结构,但是块头以下的部分(块的内容)被损坏,可能引起不同的 ORA-600 错误。逻辑损坏详细的损坏信息通常不打印在 alert 告警日志中,但是 DBV 将报告逻辑损坏的块。
3、 坏块校验
3.1 DBVERIFY ( D BV )
dbv 工具不能验证联机 Redo 日志、归档日志、控制文件和 R MAN 备份集,只能用于数据文件的块验证。 D BV 有两种命令行接口,一是验证数据文件的数据库,二是验证段(在验证段时需要查询的视图包括: S YS.SYS_DBA_SEG 和 S YS.SYS_USER_SEGS )。
DBV 要求 file 参数后面跟的必须是一个包含扩展名的文件,所以如果数据库使用裸设备作为存储方式,那么就必须使用 ln 命令连接裸设备一个带扩展名的文件,然后使用 D BV 工具通过对链接文件的验证实现对裸设备数据文件的验证。如果是验证存储在 A SM 中的数据文件,那么需要指定用户名和密码,如果不指定用户名和密码,那么将收到 D BV-00008:USERID must bu SPECIFIED FOR OSM files 的报错。
( 1 ) F S 中: dbv file= /oradata/test01.dbf blocksize=8192
( 2 ) A SM 中: dbv file=+DATA/orcl/datafile/user.dbf userid=sys/mc
( 3 )验证段,其中 segment _id 参数格式为:表空间 I D ,段头所在数据文件号,段头数据块号:
select tablespace_id,header_file,header_block from
sys.sys_dba_segs where owner='MC' and segment_name='TAB1'
dbv userid=sys/mc segment_id=36.12.130
3.2 ANALYZE
A nalyze 命令通过分析数据库对象,为优化器收集数据库对象的统计信息,以便优化器生成准确的执行计划。同时,他也能检查某个表或索引是否存在损坏的情况。 A NALYZE 执行坏块检查,但是不会标记坏块为 C ORRUPT ,检测结果保存在 U SER_DUMP _ DEST 目录下的用户 T RACE 文件中。
ANALYZE TABLE/INDEX XXX VALIDATE STRUCTURE;
3.3 EXP
对于包含坏块的表执行导出操作,会收到相关的错误信息( O RA-01578 )。 E xp 坏块检查不会发现的坏块类型包括: H WM (高水位线)以上的坏块、索引中存在的坏块、数据字典中存在的坏块。对于这种情况,在非归档模式无法通过块恢复修复块的情况下,有如下两种处理方法:
方法 1 :启用 1 0231 事件。通过设置 1 0231 诊断事件可以在导出的时候让 O racle 忽略表损坏的数据库, 1 0231 是 Oracle 的内部诊断事件,设置在全表扫描时跳过坏块的数据块,只导出包含正确块的数据,只导出包含正确块的数据,之后把表删除,再把导出的表数据导入新表,从而修复该表。
-- ( 1 )启用 1 0231 诊断事件
S QL> alter system set events='10231 trace name context forever,level 10';
- - ( 2 )禁用 1 0231 诊断事件
S QL> alter system set events='10231 trace name context forever,level 0';
方法 2 :使用 D BMS_REPAIR 包标记损坏的块。可以使用 D BMS_REPAIR 包标记损坏的数据库对象,这样 Oracle 在对损坏的对象执行全表扫描的时候会跳过损坏的块。
SQL> exec dbms_repair.skip_corrupt_blocks(user,'table name ');
3.4 RMAN
RMAN 可以检查块是否被损坏,如果备份数据数据库中包含有坏块,那么将会收到错误。
RMAN> backup validate datafile 6;
RMAN> backup validate database;
RMAN> backup validate check logical database archivelog all;
4、 查询坏块对应的对象
-- 确定坏块对应的对象
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;
SEGMENT_TYPE OWNER SEGMENT_NAME
------------------ ----------------- ------------------------------------
INDEX LC1019999 PK_ZJTEMPMXCXHJ19291