虎年初十ORACLE資料庫恢復案例

rainnyzhong發表於2010-02-24

Author: Rainny

Date: 2010-2-23

虎年剛過,就接手了一個非常困難的ORACLE資料庫恢復的CASE

資料庫經歷了不正常斷電,STARTUP ORACLE時報:

ORA-01172: recovery of thread 1 stuck at block 3859656 of file 6

ORA-01151: use media recovery to recover block, restore backup if needed

檢視ALERTLOG,發現前面已經有幾個錯誤了:

ORA-00600: internal error code, arguments: [kdxlin:psno out of range], [], [], [], [], [], [], []

Hex dump of (file 3, block 30968) in trace file /data/app/oracle/admin/ora33/bdump/ora33_p003_6219.trc

Corrupt block relative dba: 0x00c078f8 (file 3, block 30968)

Fractured block found during crash/instance recovery

Data in bad block:

type: 6 format: 2 rdba: 0x00c078f8

last change scn: 0x0000.92db87df seq: 0x1 flg: 0x06

spare1: 0x0 spare2: 0x0 spare3: 0x0

consistency value in tail: 0x4a500601

check value in block header: 0x60f

computed block checksum: 0x43d0

Reread of rdba: 0x00c078f8 (file 3, block 30968) found same corrupted data

看這個情況是發生了塊損壞,根據以往的經驗,不正常斷電的情況下,redoundo都可能發生損壞,導致資料不一致,ORACLE無法自動完成例項恢復,導致資料庫打不開。

問了客戶有沒有備份可用,回答是沒有備份。只有邏輯備份,且是年前的備份。客戶希望儘快恢復DB的正常執行。這個DB大概有將近100G,由於客戶想要儘快恢復,沒有時間對現場進行備份,所以在無路可退的情況下進行了下列操作,結果錯誤百出,中間不斷冒出新問題,其中細節在此不詳述,事後我給自己新增了一條原則:在沒有做現場備份的情況下不要給客戶做此類恢復。因為,萬一恢復不成功,我沒有回退的餘地,很難和客戶解釋和交代。懂得技術的人可能會理解我,但要是碰到不懂的客戶,可能以為是我搞砸了。總之,簡而言之,資料庫備份很重要,在沒有備份的情況下恢復ORACLE資料庫,壓力很大。粗略的描述一下過程,以記之:

RMAN嘗試對資料庫進行恢復,釋出RECOVER DATABASE命令(雖然沒有備份)碰碰運氣,看現有的REDO能否完成資料庫的恢復,結果報錯,提示要RESTORE備份。檢視ALERTLOG,發現是REDO有問題,由於沒有備份可RESTORE,嘗試開啟隱含引數:_allow_resetlogs_corruption,再次open資料庫,還是不成。

alter session set events '10015 trace name adjust_scn level 1增加SCN值,再次open db,情況發生了一些改變,這次報了ORA-006002662錯誤,這是在開啟隱含引數:_allow_resetlogs_corruption後通常都會遇到的錯誤,看到這個錯誤,我心裡稍微有數,以為再搞幾下就可以順利開啟DB了。然情況比我想象的複雜。如果ORA-006002662錯誤中第三個引數和第五個引數差別很小,那麼就可以透過多次開啟關閉資料庫例項的方式來增加SCN的值。

我重試了3OPEN,都不能成功開啟DB,再次嘗試增加SCN

ALTER SESSION SET EVENTS '10015 TRACE NAME ADJUST_SCN LEVEL 10';

對於10g,預設情況_ALLOW_ERROR_SIMULATIONFALSE,這會阻止ADJUST_SCN,所以要做ADJUST_SCN必須設定這個隱含引數為TRUE,這是使用EVENTS調整SCN的前提條件。

反覆RESTART DB,都沒能成功開啟,搞了幾次,又出現新的錯誤:

ORA-00600: internal error code, arguments: [4193], [4306], [4309], [], [], [], [], []

看來UNDO也出現了問題。啟用另外一個隱含引數:_CORRUPTED_ROLLBACK_SEGMENTS

將所有的UNDO管理方式改為手工,並加入所有的UNDO SEGMENTS(可以alertlog提到的.trc檔案中查出),下面是init引數:

_allow_resetlogs_corruption=TRUE

undo_management='MANUAL'

_corrupted_rollback_segments=(rbs _SYSSMU1$,rbs _SYSSMU2$,中間省略rbs _SYSSMU10$)

我以為這次能夠順利開啟DB,結果,非常奇怪,資料庫又報出最初出現的錯誤,這回換成是SYSTEM檔案了:

ORA-00604: error occurred at recursive SQL level 1

ORA-01578: ORACLE data block corrupted (file # 1, block # 60616)

ORA-01110: data file 1: '/data/oradata/ora33/system01.dbf'

中間再次嘗試了幾次假的不完全恢復,並建立了一個新的UNDO表空間,在INIT檔案中指定:

*.undo_tablespace=undotbs2

並以PFILE重新建立SPFILE

SQL> create spfile from pfile='/home/oracle/initora33.ora';

File created.

反覆以RESETLOGS開啟DB,直到最後看到下列資訊:

SQL> alter database open resetlogs;

alter database open resetlogs

*

ERROR at line 1:

ORA-01248: file 30 was created in the future of incomplete recovery

ORA-01110: data file 30: '/data/oradata/ora33/undotbs2.dbf'

經過幾次重啟,最後,終於成功的OPEN ORACLE

SQL> alter database open resetlogs;

Database altered.

到此,我的眼睛已經將近2個小時沒有離開電腦螢幕了。水也忘了喝一口,我站起身,通知客戶EXP資料庫,後面用DBCA重建DB,並匯入資料的過程輕車熟路,非常順利,到下午下班之前,資料庫順利恢復執行。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/684234/viewspace-1031413/,如需轉載,請註明出處,否則將追究法律責任。

相關文章