[Oracle] データ・ファイル破損時のメディアリカバリ方法 | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

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