Oracleを運用中、ごくまれにデータ・ファイルに破損が生じることがあります。
そんな時、該当データ・ファイルのバックアップとバックアップ以降のREDOログが全て揃っている場合は、完全メディアリカバリによって容易に復旧することができます。
例えば、何か処理を実行した際に、以下のようなエラーが発生した場合...
ORA-01115: ファイル11(ブロック番号332831)からの読込みI/Oエラーが発生しました。
ORA-01110: データ・ファイル11: 'C:\ORACLE\ORADATA\ORCL\USERS01.DBF'
ORA-27091: skgfqio: I/Oをキューできません。
ORA-27070: skgfdisp: 非同期の読込み/書込みに失敗しました。
OSD-04006: ReadFile()に失敗しました。ファイルからの読込みができません
O/S-Error: (OS 23) データ エラー (巡回冗長検査 (CRC) エラー) です。
この時、エラーが発生したデータ・ファイル(C:\ORACLE\ORADATA\ORCL\USERS01.DBF)のバックアップと、バックアップ以降のREDOログ(アーカイブ、オンライン共)が全て揃っていれば復旧可能です。
メディアリカバリには何通りかのやり方がありますが、どの方法でも同じ結果が得られるため、状況に応じてやりやすい方法でリカバリすればいいようです。
データベースをクローズした状態での完全メディアリカバリ
- データベースをシャットダウンします。
SHUTDOWN IMMEDIATE
- 破損したデータ・ファイルをリストアします。
- OSコマンドやバックアップソフトを使用してデータ・ファイルをバックアップからリストアします。
- データベースをマウントします。
STARTUP MOUNT
- データベースをリカバリします。
RECOVER DATABASE
RECOVER DATABASEコマンドをオプションなしで実行すると、適用するREDOログを1つ1つ確認してきます。- REDOログを自動的に適用させたい場合は、AUTOMATICオプションを付けるか、
RECOVER AUTOMATIC DATABASE
RECOVER DATABASEコマンドを実行する前にSET AUTORECOVERY ONを実行しておきます。SET AUTORECOVERY ON
リカバリが完了するとログが適用されました。 メディア・リカバリが完了しました。
というメッセージが出力されます。 - データベースをオープンします。
ALTER DATABASE OPEN;
データベースをオープンした状態での完全メディアリカバリ
- リカバリの必要な表領域をオフラインにします。
ALTER TABLESPACE USERS OFFLINE TEMPORARY;
- 破損したデータ・ファイルをリストアします。
- OSコマンドやバックアップソフトを使用してデータ・ファイルをバックアップからリストアします。
- 表領域をリカバリします。
RECOVER TABLESPACE USERS
リカバリが完了するとログが適用されました。
というメッセージが出力されます。
メディア・リカバリが完了しました。- 表領域をオンラインにする。
ALTER TABLESPACE USERS ONLINE;
リカバリの必要なデータ・ファイルの確認方法
リカバリの必要なデータ・ファイルはV$RECOVER_FILEを参照することによって得ることができます。SELECT * FROM V$RECOVER_FILE; FILE# ONLINE ONLINE_STATUS ERROR CHANGE# TIME ----- -------------- -------------- ---------------- ---------- -------- 7 ONLINE ONLINE FILE NOT FOUND 0
データファイル名、表領域名も合わせて取得したい場合は、V$DATAFILE、V$TABLESPACEを結合します。
COL FILE# FORMAT 999 COL FILE_NAME FORMAT A36 COL TABLE_SPACE_NAME FORMAT A10 COL STATUS FORMAT A7 COL ERROR FORMAT A16 SELECT RF.FILE#, DF.NAME FILE_NAME, TS.NAME TABLE_SPACE_NAME, DF.STATUS, RF.ERROR, RF.CHANGE#, RF.TIME FROM V$RECOVER_FILE RF, V$DATAFILE DF, V$TABLESPACE TS WHERE DF.FILE# = RF.FILE# AND TS.TS# = DF.TS# / FILE# FILE_NAME TABLE_SPAC STATUS ERROR CHANGE# TIME ----- ------------------------------------ ---------- ------- ---------------- ---------- -------- 7 C:\ORACLE\ORADATA\ORCL\USERS01.DBF USERS ONLINE FILE NOT FOUND 0