【Oracle】指定したテーブルのみリストアする方法|impdp・RMAN RECOVER TABLE・FLASHBACK・table_exists_action まで解説

【Oracle】指定したテーブルのみリストアする方法|impdp・RMAN RECOVER TABLE・FLASHBACK・table_exists_action まで解説 Oracle

Oracle で「特定のテーブルだけを復元したい」場面は多くあります。誤った DELETE / TRUNCATE の復旧、本番テーブルの検証環境へのコピー、バージョン戻しなど、テーブル全体ではなく一部だけのリストアが必要なケースです。

Oracle にはテーブル単位のリストア方法が複数あり、状況に応じて最適な方法が異なります。本記事では、impdp(Data Pump Import)RMAN RECOVER TABLE(12c 以降)FLASHBACK TABLECTAS + DB Link の 4 方式を比較しながら、table_exists_actionREMAP パラメータ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 方式の比較と使い分けの判断基準
スポンサーリンク

テーブル単位リストアの 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

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 / データ移行する方法が最も安全です。

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 の方が圧倒的に速いです。

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 保持期間(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 でコピー
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 するには?
Aexpdp ... 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 完全解説」、リストア時のテーブル除外は「リストア時に特定テーブルを除外する方法」も併せて参照してください。