[概要]
表を TRUNCATE した場合はロールバックを行うことはできず、そのデータを通常の方法で
復旧することはできません。データベース全体を不完全メディア・リカバリにて回復する
か、表領域の Point-in-Time リカバリを利用することで復旧することは可能ですが、この
文書では、以下の手順で TRUNCATE した表のみを復旧します。
・データベースのバックアップを利用してダミーのデータベースを作成
・ダミーのデータベースを TRUNCATE の直前まで不完全メディア・リカバリにて回復
・ダミーのデータベースより該当の表をエクスポートで取得
・取得したエクスポート・ダンプを利用し元のデータベースへインポート
[対象リリース]
Oracle Database 10g Release 1 (10.1.0)
Oracle9i Database Release 2 以前のバージョンをご使用の場合には以下のKROWNを参照
して下さい。
Document 1726281.1(KROWN:80784) TRUNCATE した表を復旧する方法
[対象プラットフォーム]
すべてのプラットフォーム
[詳細]
0.前提
この文書は以下を前提としています。
・データベース・ログ・モードを ARCHIVELOG モードで運用している。
以下のコマンドでデータベース・ログ・モードを確認できます。
SQL> archive log list
データベース・ログ・モード アーカイブ・モード
...
・正しくデータベースのバックアップを取得している。
バックアップの取得方法は オンライン・バックアップ でも コールド・バックアップ
でも構いません。
RMANのバックアップ・セットではなく、ユーザ管理バックアップを使用します。
・ダミーのデータベースは、元のデータベースと同じバージョンのプラットフォームで
同じOracleのバージョンを利用している。
(同一サーバでも別サーバでも構いません。別サーバでファイル転送にFTPを利用される
場合には、必ずbinaryモードを利用して下さい。)
1.元のデータベースでの準備
手順1-1.TRUNCATEを実行した日付とデータファイルを確認する
オブジェクトを TRUNCATE で切り捨てた場合、ディクショナリ・ビュー DBA_OBJECTS の
LAST_DDL_TIME にその日時が記録されます。そのため、以下のSQL文を実行することで
TRUNCATE を実行した日時を取得することが可能です。同時に表領域も確認します。
SQL> alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';
SQL> col owner for a10
SQL> col object_name for a20
SQL> select a.owner, a.object_name, a.object_type, a.last_ddl_time, b.tablespace_name
2 from dba_objects a, dba_tables b
3 where a.owner='SCOTT'
4 and a.object_name='EMP' and a.object_name=b.table_name;
OWNER OBJECT_NAME OBJECT_TYPE LAST_DDL_TIME
---------- -------------------- ------------------- -------------------
TABLESPACE_NAME
------------------------------
SCOTT EMP TABLE 2004-03-10 01:05:34
USERS
※ TRUNCATE後に別のDDLを実行した場合にはLAST_DDL_TIMEは最後に実行したDDLの
日時となります。その場合はおおよその日時を利用するか、Document 1723311.1(KROWN:68872) の手順で
LogMiner を利用してTRUNCATEした日時を特定して下さい。
データファイルを確認するため上記で確認できた表領域より以下を実行します。
SQL> select file_name, file_id, tablespace_name
2 from dba_data_files
3 where tablespace_name='USERS';
FILE_NAME
-----------------------------------------------
FILE_ID TABLESPACE_NAME
---------- ------------------------------
/home/oracle/oradata/ora9204/users01.dbf
4 USERS
手順1-2.制御ファイルの CREATE 文をトレース・ファイルに出力
以下のALTER文にて、制御ファイルの CREATE 文をトレース・ファイルに出力します。
SQL> alter database backup controlfile to trace;
CREATE CONTROLFILE 文を含むトレース・ファイルが、初期化パラメータ USER_DUMP_DEST
で指定されるディレクトリに作成されます。
手順1-3.カレントのオンラインREDOログをアーカイブ
元のデータベースでカレントを含むオンラインREDOログをアーカイブします。
SQL> alter system archive log current;
2.表の復旧作業
元のデータベースのデータファイルのバックアップやアーカイブREDOログ・ファイル
を利用して、ダミーのデータベースを構築します。
ダミーのデータベースの SID とデータベース名は以下の通りとします。
SID : dummy
データベース名 : dummy
手順2-1.必要なファイルを準備
作業用のディレクトリを作成し、今後の作業に必要な以下のファイルをそのディレクトリ
に準備します。ここでは '/tmp/dummy' とします。
(1) 初期化パラメータ・ファイル
元のデータファイルで利用している初期化パラメータを元にします。
最低限以下のパラメータが必要です。ここではファイル名を initdummy.ora とします。
compatible=10.1.0.2.0 /* 元のデータベースと一致させる */
control_files='/tmp/dummy/control01.ctl' /* 作業用のディレクトリを指定 */
db_block_size=8192 /* 元のデータベースと一致させる */
db_name='dummy' /* 作業用のデータベース名を設定 */
undo_management='AUTO' /* 元のデータベースと一致させる */
undo_tablespace='UNDOTBS1' /* 元のデータベースと一致させる */
log_archive_format = arch%t_%s.arc /* 元のデータベースと一致させる */
log_archive_dest_1='LOCATION = /tmp/dummy' /* 作業用のディレクトリを指定 */
※ ロールバック・セグメントを使用している場合には、rollback_segments を
設定し、undo_management、undo_tablespace は設定しないで下さい。
(2) データファイルのバックアップ
以下の表領域を構成するデータファイルのバックアップが必要となります。
TRUNCATEの実行以前に取得されているバックアップを利用する必要があります。
・システム表領域
・SYSAUX表領域
・UNDO表領域(もしくはロールバック・セグメントを構成する表領域)
・TRUNCATEしたオブジェクトを含む表領域
(3) アーカイブREDOログ・ファイル
上記(2)で使用するバックアップの取得時点のアーカイブREDOログ・ファイルから、
上記 手順1-3.でアーカイブしたものを含む全てのアーカイブREDOログ・ファ
イルが必要となります。
手順2-2.環境変数の設定
環境変数 ORACLE_SID をダミーのデータベースに合わせます。
cshの場合:
setenv ORACLE_SID dummy
sh,kshの場合:
ORACLE_SID=dummy; export ORACLE_SID
Windowsの場合:
set ORACLE_SID=dummy
※ その他のOracle関連の環境変数は適切に設定されていることを前提としています。
手順2-3.ダミーのデータベース用に制御ファイルを作成
上記 手順1-2. で取得した CREATE CONTROLFILE 文を編集します。この CREATE
CONTROLFILE 文を /tmp/dummy/create.sql として保存します。
STARTUP NOMOUNT pfile=/tmp/dummy/initdummy.ora
CREATE CONTROLFILE SET DATABASE "DUMMY" RESETLOGS NOARCHIVELOG
^^^ ^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^
-- MAXLOGFILES 5
-- MAXLOGMEMBERS 3
-- MAXDATAFILES 100
-- MAXINSTANCES 1
-- MAXLOGHISTORY 226
LOGFILE
GROUP 1 '/tmp/dummy/redo01.log' SIZE 4M,
GROUP 2 '/tmp/dummy/redo02.log' SIZE 4M
DATAFILE
'/tmp/dummy/system01.dbf',
'/tmp/dummy/sysaux01.dbf',
'/tmp/dummy/undotbs01.dbf',
'/tmp/dummy/users01.dbf' ★ <== 手順1-1で確認したデータファイルを指定します
CHARACTER SET JA16SJIS;
^^^^^^^^
※ STARTUP NOMOUNT では pfile オプションを利用し 手順2-1.(1) の初期化パラ
メータ・ファイルを指定します。
※ 各ファイルのパスは 手順2-1.で作成した作業用のディレクトリにして下さい。
※ CREATE CONTROLFILE文の各オプションについて解説します。
SET : データベース名を変更しますのでSETを指定して下さい。
RESETLOGS : 不完全メディア・リカバリを実施しますのでRESETLOGSを指定して
下さい。
NOARHIVELOG : ダミーのデータベースはARCHIVELOGである必要はありません。
MAXxxx : 指定してもしなくても構いません。
DATAFILE : 手順2-1.(2)のファイルのみを指定して下さい。
LOGFILE : RESETLOGS を行いますので既存のファイル名/サイズを使用する
必要はありません。
CHARACTER SET : 元のデータベースに合わせて下さい。
手順2-4.CREATE CONTROLFILE 文を実行し制御ファイルを作成
上記 手順2-3.で編集した CREATE CONTROLFILE 文を SQL*Plus から実行します。
% sqlplus '/ as sysdba'
SQL> @/tmp/dummy/create.sql
手順2-5.メディア・リカバリを実施
手順1-1.で確認した TRUNCATE を実行した日時より前の日時まで不完全リカバリを
実施します。プロンプトが戻りますので、auto と指定して下さい。
SQL> recover database using backup controlfile until time '2004-04-01 16:07:43';
ORA-00279: 変更150762(04/05/2004 20:28:33で生成)にはスレッド1が必要です
ORA-00289: 検討すべきログ・ファイル:/tmp/dummy/arch1_12.ARC
ORA-00280: 変更150762(スレッド1)は順序番号12に存在します。
ログの指定: {<RET>=suggested | filename | AUTO | CANCEL}
auto
ログが適用されました。
メディア・リカバリが完了しました。
手順2-6.データベースをOPEN
不完全メディア・リカバリのため RESETLOGS オプションを利用してデータベースをOPEN
します。
SQL> alter database open resetlogs;
手順2-7.TRUNCATEした表をエクスポート
ダミーのデータベースからTRUNCATEした表をエクスポートします。
% exp scott/tiger tables=emp file=emp.dmp log=imp.log
手順2-8.表をインポート
上記 手順2-7.でダミーのデータベースから取得したエクスポート・ダンプを利用
して元のデータベースに表をインポートします。
% imp scott/tiger tables=emp file=emp.dmp log=exp.log ignore=y
※ 表自体が存在することを考慮し ignore=y を指定しています。
以上で表の復旧は終了です。
これらの手順を実施される場合には、実際にテストを行い手順を明確にした上で実施して
下さい。
データファイルを扱いますので、誤って元のデータベース関連のファイルを削除するなど
手順のミスが生じることがないよう、細心の注意の上で作業を行って下さい。