有时oracle的数据文件并没有完全被损坏,而是只损坏了某些数据块。产生的原因主要是间断或随机的I/O错误或是内存块的错误。这时可以不用做整个数据文件的恢复,使datafile仍然处在在线的状态。对此可以进行下面几种处理操作。 ** oracle 9i 以后可以使用blockrecover命令(BMR):
4 i* A( I7 q; [0 h1 r' E. n 可以先通过视图v$database_block_corruption获得当前被损坏的数据块信息。此视图中记录了物理和逻辑两类block corruption。5 {. v n# O9 L) y
@ 物理的corruption:无法辨识该数据块,checksum、header、footer校验错误
/ k0 }( I w/ ?' ^4 @5 C, |0 f! X @ 逻辑corruption:chechsum、header、footer校验是正确的,但是该数据块的内容时不一致的。
: L6 T. A( i: d+ l/ f 注意:BMR是不能用于恢复逻辑上的corruption的。在backup命令中checksum的校验是默认开启的,可以通过NOCHECKSUM选项属性关闭。逻辑的校验默认是关闭的,可以在backup、restore、recover、validate命令中添加CHECK LOGICAL开启。
( j2 b3 G' O) n8 h$ y$ b 具体的操作方法为:
1 r$ o) ^" r1 A6 `0 \3 T rman> blockrecover datafile n1 block n1b1,n1b2 datafile n2 block n2b1,n2b2;
5 L U; A% T4 s# P! D ** 对于用户管理的备份和恢复方法。如果要恢复损坏的DB,只能进行整个数据文件的恢复。
% O& a: Z9 Y {" p! {6 m sql> alter database datafile 2 offline;+ J8 c4 N0 X9 u1 u: a; J+ S; J% J
sql> host ‘cp /backup/datafile1.bak /opt/demo/datafile1.dt’;
( L( Y+ F) z+ Z1 k sql> recover automatic datafile 2;2 n5 K- P; t9 [' p; u2 c4 m/ ~0 s
sql> alter database datafile 2 online;3 x& x8 g7 L' g5 H9 @: B
** 如果对于存在corruption block的表的使用不频繁,在可以忍受的情况下,可以先屏蔽这些blocks,待以后再恢复。这就要使用dbms_repair包了。具体如下:
5 g: l3 k' ^6 }% Y! | @ 建立修复表(修复表用于存放表、表分区或索引的损坏块信息)。
$ s- A- s, ?2 x6 o sql> exec dbms_repair.admin_tables(’REPAIR_TABLE’, DBMS_REPAIR.REPAIR_TABLE, DBMS_REPAIR.CREATE_ACTION);/ s7 C! Z$ ^: A5 ]; w0 L n
@ 确定损坏块的个数; {! s" l* f" l' M& q6 N+ `+ t" J
sql> var cc number
: F0 ]0 K2 a# e9 A sql> exec dbms_repair.check_object(’TBSPNAME’, ‘TABNAME’, corrupt_count=>:cc);* q5 j2 D+ A5 ^$ d/ y9 o* V4 N
sql> print cc3 y" y( d* x' c
@ 标记损坏块。
) V7 d7 T5 m, ^5 F/ \4 r sql> var fc number3 B5 L- b' x. b6 }! g. L. }- y
sql> exec dbms_repair.fix_corrupt_blocks(’TBSPNAME’, ‘TABNAME’,fix_count=>:fc);) z& d1 E4 F M
sql> print fc;
$ }' Z' Y2 [" h) z. p @ 跳过损坏块。此操作可以使涉及到损坏块的查询sql继续执行,跳过该blocks,但是对于DML,则仍会显示错误信息。' T7 K* o9 i! f
sql> exec dbms_repair.skip_corrupt_blocks(’TBSPNAME’, ‘TABNAME’);& f! P R' Q+ n& ]1 i( ?! u
@ 确定指向损坏块的索引入口。当上面确定了表的损坏块后,仍有可能存在索引指向损坏块,这些索引称为“孤立键值”。对此可以使用dbms_repair包对孤立键值进行管理:
% @6 a H' }: O3 k- Z sql> exec dbms_repair.admin_tables(’ORPHAN_TAB’, DBMS_REPAIR, ORPHAN_TABLE, DBMS_REPAIR, CREATE_ACTION);5 h( w* q, A/ _2 K' ~2 j0 D
sql> var kc number
3 I% j+ \" v, s. A7 y' z sql> exec dbms_repair.dump_orphar_keys(’TBSPNAME’,'INDEXNAME’, orphan_table_name=> ‘ORPHAN_TAB’, key_count=> :kc);
$ Z/ X: f, p, S- k sql> print kc; |