4. 具体处理方法的介绍
/ [8 G }8 D2 [1 T1 q
C# J! o1 g" C5 O! Z 恢复数据文件方法: 0 E+ j, J6 {" L2 |
如果数据库是归档方式下,并且有完整的物理备份,就可以使用此方法来恢复。
v5 b" r9 n' C- P. H- H a1 j* b. l 步骤如下: 5 B2 d* X r1 i$ Z" e! z" g
(1) 先offline受影响的数据文件,执行以下的语句: : U# v0 [! s* }& X e
, \! S: R1 p$ J1 G5 {5 B1 m5 [' k; mALTER DATABASE DATAFILE ’name_file’ OFFLINE;
0 p/ I( v* A9 l5 p4 `, W' o5 H% s$ B (2) 保留有坏块的数据文件,然后拷贝备份的数据文件。如果恢复的数据文件要求路径不同,执行以下的语句:
7 x7 `& `0 U' N" ^! Y# [! jALTER DATABASE RENAME FILE ’old_name’ TO ’new_name’; / L1 b( E4 t' U6 M
2 O$ S9 z9 U: D* y% Q- C
(3) 恢复数据文件,执行以下语句:
9 @* t! y9 r2 K3 |- q: IRECOVER DATAFILE ’name_of_file’; + t5 X. j8 Y, d3 r. b8 a
4 t/ P$ M* i' |
(4) Online恢复后的数据文件,执行以下的语句: 8 L- C/ i$ u# ]; B
1 l& T7 f/ j8 a o: b- AALTER DATABASE DATAFILE ’name_of_file’ ONLINE;
& W T. k: w; q9 ?) v. l, Y& b 只恢复坏的block(9i以上版本可用) 9 C3 `) ?, s5 v: f/ s
( X( M8 B+ w, x! L. z) n+ f 使用这种方法要求数据库版本是9.2.0以上,要求配置了Rman的catalog数据库,数据库为归档方式,并且有完整的物理备份。
* q9 ~- V& ]; U# d' L% P i步骤如下:
) k- z5 m5 p7 Z# x" G3 r" v; n使用RMAN的BLOCKRECOVER命令 : 9 w$ ]" {+ q& Z Y; }, h
4 o" J2 Y& |. P& J
Rman>run{blockrecover datafile 5 block 11,16; } : j+ e8 A* D6 M% f' `0 V) G
) S. I# \- G* b: ?
也可以强制使用某个SCN号之前的备份,恢复数据块。
! U- h0 u2 @4 L" J! {Rman>run{blockrecover datafile 5 block 11,
6 [" K. q2 i( c16 restore until sequence 8505; }
" P9 _6 Z. ]8 g* v ^' [ N/ P/ T8 U
4 h: |+ e4 J" ~1 |- H- p y& I V* n 通过ROWID RANGE SCAN 保存数据 : ?' m1 z9 |; r4 z r% m. M
$ b1 x$ i# E! V0 e
(1) 先取得坏块中ROW ID的最小值,执行以下的语句: 8 M$ @7 b' _& ~" ]
SELECT dbms_rowid.rowid_create(1,, + Q0 {: h5 D2 ?* F
,,0) from DUAL; 4 l3 T, ~* z$ b! r" w8 I
" r `& G; g5 ]! e% \7 R g (2)取得坏块中的ROW ID的最大值,执行以下的语句: : {$ I/ l0 O# q! U0 \
SELECT dbms_rowid.rowid_create(1,, 4 @) O$ J2 b# X7 M# ~! a. i9 Q
,+1,0) from DUAL / Z, a9 }9 J& b7 `
% \. J, |/ H* ] (3)建议一个临时表存储那些没有坏块的数据,执行以下的语句: " E# }4 \0 e' p! ^' {
h! g" |6 U1 F$ t' G# j* `
CREATE TABLE salvage_table & o: M f$ l3 w" ^) O( P0 Y
AS SELECT * FROM corrupt_tab Where 1=2; * v; s& b e. t# z/ {* o, j
/ J) t+ s, s1 C5 l2 h4 }- B* C! Q' [6 v (4) 保存那些不存在坏块的数据到临时表中,执行以下的语句:
3 Q2 W! K. Z( A' |. a+ u0 A! ^9 k2 U
INSERT INTO salvage_table SELECT /*+ ROWID(A) , ~, U0 T' ~ d" `6 n! g/ Q3 i- R# O
*/ * FROM A WHERE rowid < ’’; 2 u, l/ J) N: |; [
INSERT INTO salvage_table SELECT /*+ ROWID(A) / b) ^6 q" f* x0 m1 z9 w
*/ * FROM A WHERE rowid >= ’‘;
, \8 u- y; z3 u
) {3 o. K+ g+ d0 K$ n) k (5) 根据临时表中的数据重建表,重建表上的索引,限制。 . w$ V. W4 i* Q2 a9 C7 E g& {
使用10231诊断事件,在做全表扫描的时候跳过坏块
8 c( y/ v' t* r5 J# ~ 可以在session级别设定: - K& K* N2 ^5 U; Z7 |6 M# @
ALTER SESSION SET EVENTS ’10231 * H) H4 _9 h: |/ [0 q {
TRACE NAME CONTEXT FOREVER, LEVEL 10’;
, A: `' z; {3 B Z O; |4 ?. w+ y8 p/ g* c+ h( M' B; ?( e
也可以在数据库级别上设定,在初始化参数中加入:event="10231 trace name context forever, level 10" ,然后重启数据库。
0 ^9 s: ?' q& h: A, {' c
% b& W5 T3 b" ~ 然后从存在坏块的表中取出不存在坏块的数据,执行以下的语句:
' w* H& C9 e, h, R1 q( q8 a3 p( `( ECREATE TABLE salvage_emp AS SELECT * FROM corrupt_table; 1 G! t, ]9 k/ n& {1 e+ B
最后rename生成的corrupt_table为原来表的名字,并重建表上的索引和限制。
3 B' }9 i% M7 b 使用dbms_repair包进行恢复 6 p7 S0 [/ U- b( l
使用dbms_repair标记有坏块的表,在做全表扫描的时候跳过坏块,执行以下的语句: " o. |" `# K* |! E O) {
Execute DBMS_REPAIR.SKIP_CORRUPT_BLOCKS
: e- q9 @7 s8 B* { s5 C* T(’’,’’); |