Oracle で「特定のテーブルだけを復元したい」場面は多くあります。誤った DELETE / TRUNCATE の復旧、本番テーブルの検証環境へのコピー、バージョン戻しなど、テーブル全体ではなく一部だけのリストアが必要なケースです。
Oracle にはテーブル単位のリストア方法が複数あり、状況に応じて最適な方法が異なります。本記事では、impdp(Data Pump Import)、RMAN RECOVER TABLE(12c 以降)、FLASHBACK TABLE、CTAS + DB Link の 4 方式を比較しながら、table_exists_action、REMAP パラメータ、parfile による複数テーブル指定まで体系的に解説します。
この記事でわかること
・impdp tables= で特定テーブルだけをリストアする方法
・table_exists_action(REPLACE / APPEND / SKIP / TRUNCATE)の使い分け
・parfile で複数テーブルをまとめて指定する方法
・REMAP_SCHEMA / REMAP_TABLE で別名リストアする方法
・RMAN RECOVER TABLE で物理バックアップからテーブルを復元する方法(12c 以降)
・FLASHBACK TABLE TO BEFORE DROP で DROP したテーブルを復元する方法
・4 方式の比較と使い分けの判断基準
・impdp tables= で特定テーブルだけをリストアする方法
・table_exists_action(REPLACE / APPEND / SKIP / TRUNCATE)の使い分け
・parfile で複数テーブルをまとめて指定する方法
・REMAP_SCHEMA / REMAP_TABLE で別名リストアする方法
・RMAN RECOVER TABLE で物理バックアップからテーブルを復元する方法(12c 以降)
・FLASHBACK TABLE TO BEFORE DROP で DROP したテーブルを復元する方法
・4 方式の比較と使い分けの判断基準
テーブル単位リストアの 4 方式比較
| 方式 | 前提条件 | リストア対象 | 速度 | 適するケース |
|---|---|---|---|---|
| impdp(Data Pump) | expdp で取得した .dmp ファイルが必要 | テーブル構造 + データ(またはデータのみ) | 高速(パラレル対応) | 定期バックアップからの復元。最も一般的 |
| RMAN RECOVER TABLE | RMAN バックアップ + ARCHIVELOG モード。12c 以降 | 特定時点のテーブル状態 | 中〜低(補助インスタンス使用) | 物理バックアップしかない場合の特定時点復元 |
| FLASHBACK TABLE | リサイクルビンが有効。または UNDO 保持期間内 | DROP されたテーブル / 過去時点のデータ | 高速 | DROP TABLE の取り消し。短時間前の誤操作復元 |
| CTAS + DB Link | 復元元のテーブルが別環境に存在 | テーブル構造 + データ | ネットワーク依存 | 別環境(本番→検証等)からのコピー |
方式選択の判断フロー
(1) DROP TABLE を取り消したい → FLASHBACK TABLE
(2) expdp の .dmp ファイルがある → impdp(最も一般的)
(3) RMAN バックアップしかない(12c 以降)→ RMAN RECOVER TABLE
(4) 別環境にテーブルが存在する → CTAS + DB Link
(1) DROP TABLE を取り消したい → FLASHBACK TABLE
(2) expdp の .dmp ファイルがある → impdp(最も一般的)
(3) RMAN バックアップしかない(12c 以降)→ RMAN RECOVER TABLE
(4) 別環境にテーブルが存在する → CTAS + DB Link
impdp(Data Pump Import)で特定テーブルをリストア
基本コマンド
Shell(impdp 基本)
# 特定テーブルのみリストア
impdp hr/password \
directory=DATA_PUMP_DIR \
dumpfile=hr_backup.dmp \
logfile=restore_employees.log \
tables=HR.EMPLOYEES
# 複数テーブルを指定
impdp hr/password \
directory=DATA_PUMP_DIR \
dumpfile=hr_backup.dmp \
logfile=restore_multi.log \
tables=HR.EMPLOYEES,HR.DEPARTMENTS,HR.JOBS
table_exists_action:既存テーブルがある場合の動作
| 値 | 動作 | 既存データ | 適するケース |
|---|---|---|---|
| SKIP(デフォルト) | テーブルが存在する場合はスキップ | 維持される | 既存データを上書きしたくない場合 |
| REPLACE | テーブルを DROP して再作成 | 全削除→再作成 | テーブルを完全に置き換えたい場合 |
| APPEND | 既存テーブルにデータを追加 | 維持(追加される) | 差分データの追加投入 |
| TRUNCATE | TRUNCATE してからデータを投入 | 全削除→投入 | テーブル構造は維持したまま データを置き換え |
Shell(table_exists_action の指定)
# 既存テーブルを置き換えてリストア
impdp hr/password \
directory=DATA_PUMP_DIR \
dumpfile=hr_backup.dmp \
logfile=restore_replace.log \
tables=HR.EMPLOYEES \
table_exists_action=REPLACE
# データだけを追加(テーブル構造はそのまま)
impdp hr/password \
directory=DATA_PUMP_DIR \
dumpfile=hr_backup.dmp \
logfile=restore_append.log \
tables=HR.EMPLOYEES \
table_exists_action=APPEND \
content=DATA_ONLY
parfile で複数テーブルを指定
Shell(parfile の作成と使用)
# parfile の内容(restore_tables.par) directory=DATA_PUMP_DIR dumpfile=hr_backup.dmp logfile=restore_tables.log tables=HR.EMPLOYEES,HR.DEPARTMENTS,HR.JOBS,HR.JOB_HISTORY table_exists_action=REPLACE # parfile を使って実行 impdp hr/password parfile=restore_tables.par
REMAP_SCHEMA / REMAP_TABLE:別名でリストア
Shell(REMAP パラメータ)
# 別スキーマにリストア(HR → TEST_HR)
impdp system/password \
directory=DATA_PUMP_DIR \
dumpfile=hr_backup.dmp \
logfile=remap_schema.log \
tables=HR.EMPLOYEES \
remap_schema=HR:TEST_HR
# 別テーブル名でリストア(EMPLOYEES → EMPLOYEES_RESTORE)
impdp hr/password \
directory=DATA_PUMP_DIR \
dumpfile=hr_backup.dmp \
logfile=remap_table.log \
tables=HR.EMPLOYEES \
remap_table=HR.EMPLOYEES:HR.EMPLOYEES_RESTORE
REMAP_TABLE で別名リストアすれば既存データを壊さない
元のテーブルを残したまま別名でリストアし、内容を確認してから RENAME / データ移行する方法が最も安全です。
元のテーブルを残したまま別名でリストアし、内容を確認してから RENAME / データ移行する方法が最も安全です。
Data Pump の詳しい使い方は「Data Pump の使い方まとめ」、ORA-31684 エラーの対処は「ORA-31684 完全解説」、データだけのインポートは「impdp でデータだけをインポートする方法」を参照してください。
RMAN RECOVER TABLE で物理バックアップからリストア(12c 以降)
Oracle 12c 以降では、RMAN の物理バックアップからテーブル単位で特定時点に復元できます。expdp のダンプファイルがなく、RMAN バックアップしかない場合に有用です。
Shell(RMAN RECOVER TABLE)
# RMAN に接続
rman target /
# 特定テーブルを 1 時間前の状態に復元
RECOVER TABLE HR.EMPLOYEES
UNTIL TIME "TO_DATE('2026-03-28 13:00:00', 'YYYY-MM-DD HH24:MI:SS')"
AUXILIARY DESTINATION '/tmp/rman_aux'
REMAP TABLE HR.EMPLOYEES:HR.EMPLOYEES_RESTORED;
# 処理の流れ:
# 1. 補助インスタンスを /tmp/rman_aux に自動作成
# 2. バックアップからDBを復元し、指定時点まで REDO 適用
# 3. テーブルを Data Pump で元のDBにインポート
# 4. 補助インスタンスを自動削除
| 前提条件 | 詳細 |
|---|---|
| ARCHIVELOG モード | データベースが ARCHIVELOG モードで動作している必要がある |
| RMAN バックアップ | リストア対象時点を含む RMAN バックアップが存在すること |
| 補助領域 | 一時的な補助インスタンス用のディスク領域が必要(AUXILIARY DESTINATION) |
| Oracle バージョン | 12c(12.1)以降 |
RMAN RECOVER TABLE は時間がかかる
内部的にデータベース全体を補助インスタンスにリストアしてからテーブルを抽出するため、小さなテーブルでもデータベースサイズに応じた時間がかかります。Data Pump のダンプファイルがある場合は impdp の方が圧倒的に速いです。
内部的にデータベース全体を補助インスタンスにリストアしてからテーブルを抽出するため、小さなテーブルでもデータベースサイズに応じた時間がかかります。Data Pump のダンプファイルがある場合は impdp の方が圧倒的に速いです。
FLASHBACK TABLE で復元する
DROP TABLE の取り消し
SQL(FLASHBACK TABLE TO BEFORE DROP)
-- リサイクルビンから復元(DROP TABLE の取り消し) FLASHBACK TABLE employees TO BEFORE DROP; -- 別名で復元 FLASHBACK TABLE employees TO BEFORE DROP RENAME TO employees_restored; -- リサイクルビンの確認 SELECT object_name, original_name, type, droptime FROM recyclebin WHERE original_name = 'EMPLOYEES';
過去時点のデータに戻す
SQL(FLASHBACK TABLE TO TIMESTAMP / SCN)
-- 行レベルのフラッシュバック(UNDO データを使用) -- テーブルの行ムーブメントを有効化(事前に 1 回だけ実行) ALTER TABLE employees ENABLE ROW MOVEMENT; -- 1 時間前の状態に戻す FLASHBACK TABLE employees TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' HOUR); -- 特定の SCN に戻す FLASHBACK TABLE employees TO SCN 12345678;
FLASHBACK TABLE の制約
・UNDO 保持期間(
・DDL(ALTER TABLE ADD COLUMN 等)を実行した後は、DDL 前の時点に戻せない場合がある
・TRUNCATE TABLE は FLASHBACK TABLE では復元できない(RMAN またはバックアップが必要)
・UNDO 保持期間(
UNDO_RETENTION)を超えた過去には戻せない・DDL(ALTER TABLE ADD COLUMN 等)を実行した後は、DDL 前の時点に戻せない場合がある
・TRUNCATE TABLE は FLASHBACK TABLE では復元できない(RMAN またはバックアップが必要)
実務パターン集
パターン(1): 誤 DELETE の復元(Data Pump)
Shell
# 手順:
# 1. バックアップダンプから別名でリストア
impdp hr/password \
directory=DATA_PUMP_DIR \
dumpfile=hr_daily_20260327.dmp \
tables=HR.EMPLOYEES \
remap_table=HR.EMPLOYEES:HR.EMPLOYEES_BK \
logfile=restore_bk.log
# 2. 差分を確認
# SELECT * FROM employees_bk MINUS SELECT * FROM employees;
# 3. 不足分を INSERT
# INSERT INTO employees SELECT * FROM employees_bk
# WHERE employee_id NOT IN (SELECT employee_id FROM employees);
# COMMIT;
# 4. 一時テーブルを削除
# DROP TABLE employees_bk PURGE;
パターン(2): 本番テーブルを検証環境にコピー
Shell
# 本番で expdp
expdp hr/password \
directory=DATA_PUMP_DIR \
dumpfile=emp_export.dmp \
tables=HR.EMPLOYEES,HR.DEPARTMENTS
# ダンプファイルを検証環境に転送
# scp emp_export.dmp testserver:/oracle/dpdir/
# 検証環境で impdp(別スキーマにリストア)
impdp test_hr/password \
directory=DATA_PUMP_DIR \
dumpfile=emp_export.dmp \
remap_schema=HR:TEST_HR \
table_exists_action=REPLACE
パターン(3): TRUNCATE してしまったテーブルの復元
Shell
# TRUNCATE は FLASHBACK TABLE では復元不可 → Data Pump を使用
# 最新のダンプから TRUNCATE 前のデータをリストア
impdp hr/password \
directory=DATA_PUMP_DIR \
dumpfile=hr_daily_20260327.dmp \
tables=HR.EMPLOYEES \
table_exists_action=APPEND \
content=DATA_ONLY
# Data Pump ダンプがない場合 → RMAN RECOVER TABLE(12c以降)
# rman target /
# RECOVER TABLE HR.EMPLOYEES
# UNTIL TIME "..."
# AUXILIARY DESTINATION '/tmp/rman_aux';
パターン(4): DROP TABLE の復元
SQL
-- リサイクルビンを確認 SELECT original_name, droptime FROM recyclebin WHERE original_name = 'EMPLOYEES'; -- 復元 FLASHBACK TABLE employees TO BEFORE DROP; -- DROP TABLE ... PURGE で削除した場合はリサイクルビンにない -- → Data Pump または RMAN で復元する必要がある
よくあるエラーと対処
| エラー | 原因 | 対処 |
|---|---|---|
| ORA-31684(オブジェクトが既存) | テーブルが既に存在する状態で table_exists_action=SKIP(デフォルト) | table_exists_action=REPLACE または REMAP_TABLE で別名リストア |
| ORA-39166(テーブルが見つからない) | .dmp ファイルに指定テーブルが含まれていない | impdp … sqlfile=check.sql で .dmp の内容を確認 |
| ORA-39002(権限不足) | IMP_FULL_DATABASE ロールがない | GRANT IMP_FULL_DATABASE TO user |
| ORA-38305(FLASHBACK 不可) | ROW MOVEMENT が無効 / UNDO 期間超過 | ALTER TABLE … ENABLE ROW MOVEMENT / Data Pump を使用 |
Shell(.dmp ファイルの中身を確認する方法)
# .dmp に含まれるテーブル一覧を確認(実際にはインポートしない)
impdp hr/password \
directory=DATA_PUMP_DIR \
dumpfile=hr_backup.dmp \
sqlfile=check_contents.sql
# check_contents.sql に CREATE TABLE 文が出力される
# → 目的のテーブルが含まれているか確認
よくある質問
Qexpdp のダンプファイルがありません。テーブルを復元できますか?
Aいくつかの方法があります。
(1) FLASHBACK TABLE: DROP の取り消し、または UNDO 保持期間内なら過去時点に戻せる
(2) RMAN RECOVER TABLE(12c 以降): RMAN バックアップがあれば特定時点のテーブルを復元可能
(3) 別環境からコピー: 検証環境やレプリカにテーブルが残っていれば DB Link + CTAS でコピー
(1) FLASHBACK TABLE: DROP の取り消し、または UNDO 保持期間内なら過去時点に戻せる
(2) RMAN RECOVER TABLE(12c 以降): RMAN バックアップがあれば特定時点のテーブルを復元可能
(3) 別環境からコピー: 検証環境やレプリカにテーブルが残っていれば DB Link + CTAS でコピー
Qtable_exists_action=REPLACE と TRUNCATE の違いは?
AREPLACE はテーブルを DROP してから再作成します(インデックス・制約も再作成)。TRUNCATE はテーブル構造を維持したままデータだけを入れ替えます。既存のインデックスや制約をそのまま維持したい場合は TRUNCATE、完全に置き換えたい場合は REPLACE を使います。
QTRUNCATE TABLE は FLASHBACK TABLE で復元できますか?
Aできません。TRUNCATE は DDL(DDL = 自動 COMMIT)であり、FLASHBACK TABLE(UNDO ベース)では復元できません。TRUNCATE の復元には Data Pump のダンプファイル、または RMAN RECOVER TABLE(12c 以降)が必要です。
QRMAN RECOVER TABLE と impdp はどちらが速いですか?
Aほぼすべてのケースで impdp の方が高速です。RMAN RECOVER TABLE は内部的にデータベース全体を補助インスタンスにリストアするため、テーブルサイズに関係なくデータベースサイズ分の時間がかかります。expdp のダンプがある場合は impdp を優先してください。
Qリストア先に同じ名前のテーブルがある場合どうなりますか?
Aimpdp のデフォルト(table_exists_action=SKIP)ではスキップされてリストアされません。REPLACE(DROP して再作成)、APPEND(既存データに追加)、TRUNCATE(データを入れ替え)から目的に合った動作を選んでください。最も安全なのは REMAP_TABLE で別名にリストアし、確認してから切り替える方法です。
Qスキーマ全体ではなく特定テーブルだけ expdp するには?
A
expdp ... tables=SCHEMA.TABLE1,SCHEMA.TABLE2 で指定します。日常的にテーブル単位のバックアップを取っておけば、障害時に impdp で迅速にリストアできます。テーブル数が多い場合は parfile にまとめると便利です。まとめ
テーブル単位のリストア方法をまとめます。
| 状況 | 推奨方法 |
|---|---|
| expdp のダンプがある | impdp tables=SCHEMA.TABLE |
| 既存テーブルを置き換えたい | impdp … table_exists_action=REPLACE |
| データだけ復元(構造は維持) | impdp … table_exists_action=TRUNCATE content=DATA_ONLY |
| 別名で安全にリストア | impdp … remap_table=OLD:NEW |
| DROP TABLE を取り消したい | FLASHBACK TABLE … TO BEFORE DROP |
| 短時間前の誤操作を取り消したい | FLASHBACK TABLE … TO TIMESTAMP |
| RMAN バックアップしかない(12c+) | RMAN RECOVER TABLE … UNTIL TIME |
| 別環境からコピーしたい | CTAS + DB Link / expdp + ファイル転送 + impdp |
Data Pump の詳しい使い方は「Data Pump の使い方まとめ」、ORA-31684 の対処は「ORA-31684 完全解説」、リストア時のテーブル除外は「リストア時に特定テーブルを除外する方法」も併せて参照してください。

