4. 具体处理方法的介绍
* h' V- o# O, ?* L Q
$ G2 }! L2 R8 x7 O. { 恢复数据文件方法: 5 C3 I0 e; v: U, r0 }+ J
如果数据库是归档方式下,并且有完整的物理备份,就可以使用此方法来恢复。 $ L; O/ Z2 g# t/ g
步骤如下:
- x* B5 ^% s8 V& p' X1 W. |' ^, q (1) 先offline受影响的数据文件,执行以下的语句:
% A* |4 H5 S1 O8 h; o; k7 t; p0 n {9 o7 Z. }
ALTER DATABASE DATAFILE ’name_file’ OFFLINE;
4 h. | [ k& L2 m# y, d6 } (2) 保留有坏块的数据文件,然后拷贝备份的数据文件。如果恢复的数据文件要求路径不同,执行以下的语句:
4 [& m/ {. x) G$ nALTER DATABASE RENAME FILE ’old_name’ TO ’new_name’; / j7 v2 A' N% a7 T7 S
" K( t6 l. f3 v" a! C' c% [+ [
(3) 恢复数据文件,执行以下语句:
9 [3 u3 [, v6 f {0 s/ v; Y0 XRECOVER DATAFILE ’name_of_file’;
# s" n" {0 D7 Y: A0 w4 k+ h. h% f( w
(4) Online恢复后的数据文件,执行以下的语句:
6 ]0 X6 B \7 X @' a; X0 k. ^! ~ c, m8 I) N% N
ALTER DATABASE DATAFILE ’name_of_file’ ONLINE;
# `% X, }9 I7 _- A3 J! m% u 只恢复坏的block(9i以上版本可用) & ^# Z6 [+ D' d9 i
, S1 a3 f% a1 I- i+ ^: z1 p
使用这种方法要求数据库版本是9.2.0以上,要求配置了Rman的catalog数据库,数据库为归档方式,并且有完整的物理备份。 $ Q+ d& }0 X. w8 K6 m0 v
步骤如下:
) G8 Q7 L2 x4 `0 o5 _. p% l使用RMAN的BLOCKRECOVER命令 : . f$ ~) k: W" w' T$ ]+ c" h/ D T
; C+ _9 ~9 W% o Q) j7 t
Rman>run{blockrecover datafile 5 block 11,16; } : }- ?. C/ I C. g" D4 C1 r( d/ \) W4 L8 T
) Y2 ]. w( I- T! q2 ` 也可以强制使用某个SCN号之前的备份,恢复数据块。
* m) ?. s q( w; l$ { Y! Z+ ?Rman>run{blockrecover datafile 5 block 11,
/ g+ l6 j7 |* v1 I b16 restore until sequence 8505; } * D$ r& N& ^& p: C' ^6 |
. p( e. e& v7 l$ @( D( p8 y4 E 通过ROWID RANGE SCAN 保存数据 ! S- C9 w& x G6 V# e
3 ?! ]8 G$ ]! L3 N
(1) 先取得坏块中ROW ID的最小值,执行以下的语句: ! e5 j1 ~) x+ ^) m; B$ ^" Q" K
SELECT dbms_rowid.rowid_create(1,, % ]* Y" y$ V. b" q
,,0) from DUAL; 9 |! S: b3 M6 X5 f
, j# t$ V$ B4 s d7 y4 K0 k" [ (2)取得坏块中的ROW ID的最大值,执行以下的语句: 1 u2 M$ r7 O& |* d; X# V% e: y
SELECT dbms_rowid.rowid_create(1,,
, Q& H6 l/ h' E9 H,+1,0) from DUAL . k# |- t, v* j& Z7 ?0 m) o
0 _7 A" l' A/ c/ Z* ^! ^2 a (3)建议一个临时表存储那些没有坏块的数据,执行以下的语句:
/ h/ v& u6 {) T/ k/ |/ k. t2 L. _& M2 ^) J7 ~# T9 h7 z
CREATE TABLE salvage_table
( ^0 x% z& Z* a' E3 o; F! \; U- r' Y* |AS SELECT * FROM corrupt_tab Where 1=2; 0 }0 t% m) k, L/ d, [+ r
7 \" p# @" P. K0 ~* p
(4) 保存那些不存在坏块的数据到临时表中,执行以下的语句: : x, ~" A, e- ] `$ d; A
) t- u8 |6 l4 U3 G; D
INSERT INTO salvage_table SELECT /*+ ROWID(A)
! y. y! Q5 U! m*/ * FROM A WHERE rowid < ’’;
0 b- N l4 R4 T C8 e3 V# JINSERT INTO salvage_table SELECT /*+ ROWID(A)
# F0 [5 {( K3 l' {% |3 z*/ * FROM A WHERE rowid >= ’‘; f1 G# V R- y! w' K/ S: u. H' A
6 O( F" _6 o0 m; l: r
(5) 根据临时表中的数据重建表,重建表上的索引,限制。 ; D; F9 {' X# v! G# b) Y
使用10231诊断事件,在做全表扫描的时候跳过坏块 : Q m5 l( U* v7 e
可以在session级别设定:
K0 [; C. g+ C' A7 F0 yALTER SESSION SET EVENTS ’10231 & }7 f0 j9 R' H9 u* `% u
TRACE NAME CONTEXT FOREVER, LEVEL 10’;
# U. S- O6 \6 l3 d
7 O) [+ v( \/ L. F. t1 f 也可以在数据库级别上设定,在初始化参数中加入:event="10231 trace name context forever, level 10" ,然后重启数据库。
5 _$ m" |4 Z8 W7 ^$ X
' z# ^6 h( e2 e0 g$ D9 F9 t6 X 然后从存在坏块的表中取出不存在坏块的数据,执行以下的语句: " s; U& z9 [ a n" e7 S
CREATE TABLE salvage_emp AS SELECT * FROM corrupt_table; # a4 ^; c/ L) @# c- Z# X
最后rename生成的corrupt_table为原来表的名字,并重建表上的索引和限制。
( K+ e1 `3 o) b 使用dbms_repair包进行恢复 , w+ R) z* |# W, g; ?- d/ V
使用dbms_repair标记有坏块的表,在做全表扫描的时候跳过坏块,执行以下的语句: $ F, F( I' g. h! |
Execute DBMS_REPAIR.SKIP_CORRUPT_BLOCKS . ~, V5 N7 K1 e/ d
(’’,’’); |