SQL> oradebug tracefile_name
/s01/admin/G10R25/udump/g10r25_ora_19749.trc
Corrupt block relative dba: 0x010d4744 (file 4, block 870212)
Bad header found during buffer read
Data in bad block:
type: 6 format: 2 rdba: 0x000d4744
last change scn: 0x0000.00000000 seq: 0xff flg: 0x04
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0x000006ff
check value in block header: 0x6323
computed block checksum: 0x0
Reread of rdba: 0x010d4744 (file 4, block 870212) found same corrupted data
*** 2012-11-08 06:23:12.564
table scan: segment: file# 4 block# 870211
skipping corrupt block file# 4 block# 870212
*** 2012-11-08 06:23:36.955
table scan: segment: file# 4 block# 870211
skipping corrupt block file# 4 block# 870212
skipping corrupted block at rdba: 0x010d4744
下面使用10231 level 10事件来避免发生ORA-01578错误,并将原坏块表复制出来:
SQL> alter session set events '10231 trace name context forever,level 10';
Session altered.
SQL> select count(*) from CORRUPT_ME;
COUNT(*)
----------
50857
SQL> create table corrupt_me_copy tablespace users as select * from CORRUPT_ME;
Table created.
SQL> analyze table corrupt_me_copy validate structure;
Table analyzed.
之后仅需要将新表rename为旧表,并重建索引即可:
SQL> alter table corrupt_me rename to corrupt_me_copy1;
Table altered.
SQL> alter table corrupt_me_copy rename to corrupt_me;
Table altered.
SQL> rebuild indexs
利用RMAN检测数据库坏块的脚本
============================
虽然我们也可以通过dbv(db file verify)工具做到对单个数据文件的坏块检测,但是直接使用RMAN的”backup validate check logical database;”结合V$DATABASE_BLOCK_CORRUPTION视图要方便地多。
Script:
1) $ rman target / nocatalog
2) RMAN> run {
allocate channel d1 type disk;
allocate channel d2 type disk;
allocate channel d3 type disk;
allocate channel d4 type disk;
}
3) select * from V$DATABASE_BLOCK_CORRUPTION ;
4) If V$DATABASE_BLOCK_CORRUPTION contains rows please run this query to
find the objects that contains the corrupted blocks:
SELECT e.owner,
e.segment_type,
e.segment_name,
e.partition_name,
c.file#,
greatest(e.block_id, c.block#) corr_start_block#,
least(e.block_id + e.blocks - 1, c.block# + c.blocks - 1) corr_end_block#,
least(e.block_id + e.blocks - 1, c.block# + c.blocks - 1) -
greatest(e.block_id, c.block#) + 1 blocks_corrupted,
null description
FROM dba_extents e, v$database_block_corruption c
WHERE e.file_id = c.file#
AND e.block_id <= c.block# + c.blocks - 1
AND e.block_id + e.blocks - 1 >= c.block#
UNION
SELECT s.owner,
s.segment_type,
s.segment_name,
s.partition_name,
c.file#,
header_block corr_start_block#,
header_block corr_end_block#,
1 blocks_corrupted,
'Segment Header' description
FROM dba_segments s, v$database_block_corruption c
WHERE s.header_file = c.file#
AND s.header_block between c.block# and c.block# + c.blocks - 1
UNION
SELECT null owner,
null segment_type,
null segment_name,
null partition_name,
c.file#,
greatest(f.block_id, c.block#) corr_start_block#,
least(f.block_id + f.blocks - 1, c.block# + c.blocks - 1) corr_end_block#,
least(f.block_id + f.blocks - 1, c.block# + c.blocks - 1) -
greatest(f.block_id, c.block#) + 1 blocks_corrupted,
'Free Block' description
FROM dba_free_space f, v$database_block_corruption c
WHERE f.file_id = c.file#
AND f.block_id <= c.block# + c.blocks - 1
AND f.block_id + f.blocks - 1 >= c.block#
order by file#, corr_start_block#;
SELECT tablespace_name, segment_type, owner, segment_name
FROM dba_extents
WHERE file_id = &fileid
and &blockid between block_id AND block_id + blocks - 1;
http://docs.oracle.com/cd/B28359_01/back