oracle坏块处理
1. 背景:
oracle坏块分为逻辑坏块和物理坏块,逻辑坏块通常是由于oracle bug引起的,有时报ora-600错;物理坏块则由于硬件或者os、内存等引起的。这里主要研究物理坏块,分为索引坏块和表坏块两大类
2. 表坏块
1. 生成坏块:
我们可以通过oracle自带的工具bbed来管理物理数据文件和块block
10g可以直接通过命令安装bbed
cd $ORACLE_HOME/rdbms/lib
make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
然后在PATH里将$ORACLE_HOME/rdbms/lib加上
11g及以上的版本需要拷贝10g的三个文件,此文件已附在文末
cp bbedus.msb $ORACLE_HOME/rdbms/mesg
cp sbbdpt.o ssbbded.o $ORACLE_HOME/rdbms/lib
cd $ORACLE_HOME/rdbms/lib
make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed
select file#||' '||name||' '||bytes from v$datafile;
vi dbfiles.txt
1 /oracle10/oradata/dgtest/system01.dbf 471859200
2 /oracle10/oradata/dgtest/undotbs01.dbf 146800640
3 /oracle10/oradata/dgtest/sysaux01.dbf 450887680
4 /oracle10/oradata/dgtest/users01.dbf 5242880
5 /oracle10/oradata/dgtest/dgtest01.dbf 104857600
6 /oracle10/oradata/dgtest/test01.dbf 104857600
vi bbed_parameter.txt
blocksize=8192
listfile=/oracle10/dbfiles.txt
mode=edit
bbed parfile= bbed_parameter.txt
密码:blockedit
BBED> show all

info

生成坏块:
(1)先确认某张表所在的表空间和块号
select dbms_rowid.ROWID_RELATIVE_FNO(rowid), dbms_rowid.ROWID_BLOCK_NUMBER(rowid),id from test1;
select segment_type,SEGMENT_NAME,PARTITION_NAME,HEADER_FILE,HEADER_BLOCK,tablespace_name from dba_segments where owner='TESTBBED' order by SEGMENT_NAME;
(2)进入bbed,modify块
modify 1000 file 6 block 13
(3)此时检测坏块,有三种方式
a. dbv
dbv file=/oracle10/oradata/dgtest/test01.dbf blocksize=8192

b. bbed verify

c. rman
RMAN> backup validate datafile 6;
*检查整个库
backup validate database;
此时会把corrupt的块记录到v$database_block_corruption中
select * from v$database_block_corruption;

(4)确认corrupt的段名和对象
由file#和block#确认segment名
SELECT SEGMENT_NAME,PARTITION_NAME,SEGMENT_TYPE FROM DBA_EXTENTS WHERE FILE_ID = 6 and 13 BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS - 1;

analyze table test1 validate structure cascade online;

清空缓存:
alter system flush buffer_cache;
报ora-01578或ora-01115错


2. 修复坏块
(1)若有物理备份,恢复后数据可能完整,也可能有丢失
list backupset;

blockrecover datafile 6 block 13;

dbv检查

(2)若无备份,数据可能有丢失
坏块中的数据一定丢失,其他好块中的数据可以通过跳过坏块的方式抢救

alter system set events '10231 trace name context forever,level 10'; ---设置跳过坏块

可以通过expdp/impdp truncate表的方式使得表恢复读写
expdp testbbed/test directory=DATA_PUMP_DIR tables=test1 dumpfile=test1.dmp
impdp testbbed/test directory=DATA_PUMP_DIR tables=test1 dumpfile=test1.dmp table_exists_action=truncate
truncate之后block不再是corrupted了,此时
alter system set events '10231 trace name context off';


(3) 对于分区表我们修复的方式有两种
a. 将整个分区exchange到同结构的表中
create table test_partition_BAK as select * from test_partition where 1=2;
alter table test_partition exchange partition p2 with table test_partition_BAK;
select count(*) from test_partition partition(p2); ---0条
此时再按照普通表的方式 跳过坏块 对test_partition_BAK进行expdp/impdp
最后再次将分区与不同表交换
alter table test_partition exchange partition p2 with table test_partition_BAK;
注意:exchange分区会使得分区表分区索引失效,exchange后需要重建p2分区的索引才行
select status, INDEX_NAME,PARTITION_NAME from user_ind_partitions;

alter index IDX_TEST_PARTITION rebuild partition p2 parallel 8 online;
b. 跳过坏块,直接将分区expdp/impdp,导入分区使用append
alter system set events '10231 trace name context forever,level 10';
expdp testbbed/test directory=export tables=test_partition:p2 dumpfile=test_partition.dmp logfile=test_partition.log
alter table test_partition truncate partition p2;
impdp testbbed/test directory=export dumpfile=test_partition.dmp table_exists_action=append
select count(*)from test_partition partition(p2);
3. 索引坏块
如果坏块出现在索引上,可能会出现如下错误

SELECT SEGMENT_NAME,PARTITION_NAME,SEGMENT_TYPE FROM DBA_EXTENTS WHERE FILE_ID = 18 and 195 BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS - 1;
经过检查发现此索引出现了坏块
(1)索引需要重建
但是如果我们按照下面的语句重建索引:
普通表:
alter index IDX_TEST1 rebuild;
在dba_segment 中会出现temporary segment,segment_name由file#.blockid构成

无法释放空间,需要我们手动释放或者修复
exec dbms_space_admin.segment_drop_corrupt('TEST',6,475); 表空间名 ,file#, blockid
SQL> select ts# from v$tablespace where name='TEST';
TS#
----------
7
alter session set events 'immediate trace name DROP_SEGMENTS level 8'; 8等于表空间number+1
这种情况下生成的temporary段较难清除,故如果索引出现坏块,建议drop索引之后,在create索引,此时没有临时段产生
drop index IDX_TEST1;
create index IDX_TEST1 on test1(id);
但是分区索引经测试,不会有临时段存留,可以直接rebuild
alter index IDX_test_partition rebuild partition P1 online parallel 8;
(2)若有物理备份,可以直接通过rman修复此block
blockrecover datafile 6 block 475;
更多推荐
所有评论(0)