【Oracle】Data Pump(expdp / impdp)完全ガイド|エクスポート・インポート・スキーマ移行・よく使うパラメータまで解説

Oracle Data Pump(expdp / impdp)は、Oracle 10g 以降に搭載された高速なデータエクスポート・インポートツールです。旧来の exp / imp コマンドに比べて大幅に高速化されており、スキーマ移行・テーブルデータのバックアップ・本番データの開発環境への移動など、DBA 業務で最も頻繁に使われるツールの一つです。

Data Pump はサーバーサイドで動作します。ダンプファイルは クライアントではなく Oracle サーバー上の DIRECTORY オブジェクトが指すディレクトリに出力されます。この点が旧来の exp/imp と大きく異なるため、まず DIRECTORY の設定から理解する必要があります。

この記事でわかること

  • DIRECTORY オブジェクトの作成と権限付与
  • expdp でスキーマ / テーブル / フルデータベースをエクスポートする方法
  • QUERY・EXCLUDE・INCLUDE によるエクスポート対象の絞り込み
  • impdp の REMAP_SCHEMA・REMAP_TABLESPACE でスキーマ名・表領域名を変えてインポートする方法
  • TABLE_EXISTS_ACTION の使い分け(SKIP / REPLACE / APPEND / TRUNCATE)
  • NETWORK_LINK で DB 間を直接転送する方法
  • 進捗の確認と実行中ジョブの操作(KILL_JOB など)
スポンサーリンク

DIRECTORY オブジェクトの作成と権限付与

Data Pump でエクスポートやインポートを実行するには、Oracle が認識できる DIRECTORY オブジェクトが必要です。DIRECTORY はサーバー上の OS ディレクトリへのエイリアスで、DBA 権限で作成してからユーザーに READ / WRITE 権限を付与します。

DIRECTORY の作成・確認・権限付与
-- DBA 権限でログインして DIRECTORY を作成する
CREATE DIRECTORY dp_dir AS '/u01/backup/datapump';
-- ※ ディレクトリは OS 上に実際に存在する必要がある(Oracle は自動作成しない)

-- DIRECTORY 一覧を確認する
SELECT directory_name, directory_path
FROM DBA_DIRECTORIES
ORDER BY directory_name;

-- ユーザーに READ / WRITE 権限を付与する
GRANT READ, WRITE ON DIRECTORY dp_dir TO hr;
GRANT READ, WRITE ON DIRECTORY dp_dir TO scott;

-- Oracle にはデフォルトで DATA_PUMP_DIR が存在する(環境による)
-- パスは SELECT * FROM DBA_DIRECTORIES WHERE directory_name='DATA_PUMP_DIR'; で確認

expdp でエクスポートする

expdp はコマンドラインから実行する OS コマンドです(SQL*Plus ではない)。基本的なパラメータと組み合わせて、スキーマ・テーブル・データベース全体のエクスポートができます。

expdp の基本的なエクスポート例
# スキーマ単位でエクスポート(最も一般的な使い方)
expdp hr/hr_password@localhost:1521/orcl   SCHEMAS=hr   DIRECTORY=dp_dir   DUMPFILE=hr_schema_%date%.dmp   LOGFILE=hr_export.log

# 複数スキーマをまとめてエクスポート
expdp system/password@orcl   SCHEMAS=hr,scott,oe   DIRECTORY=dp_dir   DUMPFILE=multi_schema_%U.dmp   FILESIZE=2G   PARALLEL=4   LOGFILE=multi_schema_export.log

# 特定テーブルだけをエクスポート
expdp hr/hr_password@orcl   TABLES=hr.employees,hr.departments   DIRECTORY=dp_dir   DUMPFILE=emp_dept.dmp   LOGFILE=emp_dept_export.log

# データベース全体(フルエクスポート)
expdp system/password@orcl   FULL=y   DIRECTORY=dp_dir   DUMPFILE=full_%U.dmp   FILESIZE=5G   PARALLEL=8   LOGFILE=full_export.log

# PARFILE(パラメータファイル)を使う場合
expdp system/password@orcl PARFILE=/home/oracle/export.par
# /home/oracle/export.par の内容:
# SCHEMAS=hr
# DIRECTORY=dp_dir
# DUMPFILE=hr_%U.dmp
# LOGFILE=hr_export.log
# COMPRESSION=ALL
# PARALLEL=4
QUERY・EXCLUDE・INCLUDE によるフィルタリング
-- QUERY: 特定の条件でデータを絞り込んでエクスポートする
-- ※ テーブル単位で条件を指定する(スキーマエクスポート時は対象テーブルを指定)
-- コマンドライン: QUERY=hr.employees:"WHERE department_id=60"
-- PARFILE 内:
-- QUERY=hr.employees:"WHERE hire_date > DATE '2020-01-01'"

-- EXCLUDE: 特定のオブジェクト種類・オブジェクトをエクスポートから除外する
-- コマンドライン例(PARFILE 推奨):
-- EXCLUDE=STATISTICS           -- オプティマイザ統計を除外(インポート後に収集する)
-- EXCLUDE=GRANT                -- 権限を除外
-- EXCLUDE=TABLE:"='TEMP_LOG'"  -- 特定テーブルを除外
-- EXCLUDE=INDEX                -- すべてのインデックスを除外(再作成するケース)

-- INCLUDE: 特定のオブジェクトだけをエクスポートする
-- INCLUDE=TABLE:"IN ('EMPLOYEES','DEPARTMENTS')"
-- INCLUDE=PROCEDURE
-- INCLUDE=TABLE,INDEX  -- テーブルとインデックスのみ

-- CONTENT: エクスポートする内容を選択する
-- CONTENT=ALL          -- データとメタデータ(デフォルト)
-- CONTENT=DATA_ONLY    -- データのみ(DDLなし)
-- CONTENT=METADATA_ONLY -- 定義のみ(データなし)

impdp でインポートする

インポートは expdp と同じ構文を使います。移行先のスキーマ名や表領域名が異なる場合は REMAP_SCHEMAREMAP_TABLESPACE で変換できます。

impdp の基本的なインポート例
# 同じスキーマ名でインポート(最もシンプル)
impdp hr/hr_password@localhost:1521/orcl_dev   SCHEMAS=hr   DIRECTORY=dp_dir   DUMPFILE=hr_schema.dmp   LOGFILE=hr_import.log

# スキーマ名を変えてインポート(本番 hr → 開発 hr_dev)
impdp system/password@orcl_dev   REMAP_SCHEMA=hr:hr_dev   DIRECTORY=dp_dir   DUMPFILE=hr_schema.dmp   LOGFILE=hr_import_remap.log

# 表領域名も変えてインポート(本番 USERS → 開発 USERS_DEV)
impdp system/password@orcl_dev   REMAP_SCHEMA=hr:hr_dev   REMAP_TABLESPACE=USERS:USERS_DEV,INDX:INDX_DEV   DIRECTORY=dp_dir   DUMPFILE=hr_schema.dmp   LOGFILE=hr_import_remap.log

# テーブル単位でインポート
impdp hr/hr_password@orcl_dev   TABLES=hr.employees   DIRECTORY=dp_dir   DUMPFILE=emp_dept.dmp   TABLE_EXISTS_ACTION=REPLACE   LOGFILE=emp_import.log

# フルインポート(新規 DB へのリストア)
impdp system/password@new_orcl   FULL=y   DIRECTORY=dp_dir   DUMPFILE=full_%U.dmp   PARALLEL=8   LOGFILE=full_import.log
TABLE_EXISTS_ACTION と TRANSFORM の使い方
-- TABLE_EXISTS_ACTION: インポート先にテーブルが存在する場合の動作
-- SKIP    : 既存テーブルをスキップ(デフォルト。データを追加しない)
-- APPEND  : 既存テーブルにデータを追記する(制約チェックあり)
-- TRUNCATE: 既存テーブルを TRUNCATE してからインポート(注意: TRUNCATE は ROLLBACK 不可)
-- REPLACE : 既存テーブルを DROP して再作成してインポート

-- TRANSFORM: インポート時に DDL を変換する
-- TRANSFORM=SEGMENT_ATTRIBUTES:N    -- ストレージ句・表領域指定を除去(REMAP_TABLESPACE と競合する場合に使う)
-- TRANSFORM=OID:N                   -- Object ID を再生成する(オブジェクト型・XMLType 使用時)

-- SQLFILE: 実際にインポートせず、実行される DDL を SQL ファイルに出力する(ドライラン)
-- impdp system/password@orcl DIRECTORY=dp_dir DUMPFILE=hr.dmp SQLFILE=dp_dir:hr_ddl.sql

-- EXCLUDE=STATISTICS: インポート後に DBMS_STATS で統計を収集するためエクスポートデータの統計を無視する
-- (インポート完了後: EXEC DBMS_STATS.GATHER_SCHEMA_STATS('HR'); で最新統計を収集)

NETWORK_LINK で DB 間を直接転送する

NETWORK_LINK を使うと、ダンプファイルを介さずに直接 DB 間でデータを転送できます。本番環境から開発環境への定期コピーや、DB 移行時に便利です。転送元 DB に対して Database Link が設定されている必要があります。

NETWORK_LINK を使った DB 間直接転送の準備
-- 転送先 DB(import を実行する DB)側で DB Link を作成する
CREATE DATABASE LINK prod_link
CONNECT TO hr IDENTIFIED BY hr_password
USING 'prod_db';  -- tnsnames.ora のエントリ名または Easy Connect 文字列

-- DB Link の接続テスト
SELECT * FROM dual@prod_link;

-- NETWORK_LINK を使ったインポート(転送先 DB で実行)
-- ※ expdp/impdp ではなく impdp に NETWORK_LINK を指定する
-- コマンドライン:
-- impdp hr/hr_password@dev_db --   SCHEMAS=hr --   NETWORK_LINK=prod_link --   REMAP_SCHEMA=hr:hr_dev --   DIRECTORY=dp_dir --   LOGFILE=network_import.log
-- ※ NETWORK_LINK 使用時は DUMPFILE が不要(直接転送)
-- ※ 転送元(prod_db)に DATAPUMP_EXP_FULL_DATABASE 権限またはスキーマ権限が必要

-- DBMS_DATAPUMP を使って PL/SQL からジョブを制御する場合の例
DECLARE
    h NUMBER;
BEGIN
    h := DBMS_DATAPUMP.OPEN(
        operation   => 'EXPORT',
        job_mode    => 'SCHEMA',
        job_name    => 'HR_EXPORT_JOB',
        remote_link => NULL,
        version     => 'COMPATIBLE'
    );
    DBMS_DATAPUMP.ADD_FILE(h, 'hr_export.dmp', 'DP_DIR');
    DBMS_DATAPUMP.ADD_FILE(h, 'hr_export.log', 'DP_DIR', filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE);
    DBMS_DATAPUMP.METADATA_FILTER(h, 'SCHEMA_EXPR', 'IN (''HR'')');
    DBMS_DATAPUMP.START_JOB(h);
    DBMS_DATAPUMP.DETACH(h);   -- バックグラウンドで実行してデタッチ
END;
/

進捗の確認と実行中ジョブの操作

DBA_DATAPUMP_JOBS と V$SESSION_LONGOPS で進捗を確認する
-- 実行中の Data Pump ジョブを確認する
SELECT job_name, operation, job_mode, state, degree, attached_sessions
FROM DBA_DATAPUMP_JOBS
WHERE state = 'EXECUTING';

-- 進捗を確認する(V$SESSION_LONGOPS)
SELECT sid, serial#, opname, sofar, totalwork,
       ROUND(sofar / NULLIF(totalwork, 0) * 100, 1) AS pct_done,
       elapsed_seconds, time_remaining
FROM V$SESSION_LONGOPS
WHERE opname LIKE 'Data Pump%'
  AND totalwork > 0
ORDER BY start_time DESC;

-- 実行中ジョブに対話的に接続する(別ターミナルから)
-- expdp attach=<job_name>
-- 接続後の操作:
--   STATUS   : 現在の進捗を表示
--   PARALLEL=8 : 並列度を変更する(実行中に変更可能)
--   KILL_JOB : ジョブを強制終了してダンプファイルを削除する
--   STOP_JOB : ジョブを停止する(後で再開可能)
--   START_JOB: 停止したジョブを再開する
--   EXIT_CLIENT: Data Pump インターフェースを抜ける(ジョブはバックグラウンドで継続)

-- 残ったジョブメタデータをクリーンアップする(失敗後など)
DROP TABLE hr.SYS_EXPORT_SCHEMA_01 PURGE;  -- ジョブ制御テーブルの削除
-- ※ テーブル名は DBA_DATAPUMP_JOBS.job_name に対応する

よくあるエラーと対処法

エラー 原因 対処法
ORA-39002: invalid operation DIRECTORY 権限がない・DIRECTORY が存在しない GRANT READ, WRITE ON DIRECTORY を確認する。DBA_DIRECTORIES で DIRECTORY の存在を確認する
ORA-39070: unable to open the log file DIRECTORY の OS パスに書き込み権限がない OS 側のディレクトリに oracle ユーザーの書き込み権限があるか確認する
ORA-39166: object not found EXCLUDE/INCLUDE で指定したオブジェクト名が存在しない オブジェクト名の大文字小文字と存在を USER_OBJECTS で確認する
ORA-31626: job does not exist ATTACH で接続しようとしたジョブが存在しない DBA_DATAPUMP_JOBS で正確なジョブ名を確認する
ORA-39127: unexpected error encountered in call to export_string 統計データのエクスポートでメモリ不足など EXCLUDE=STATISTICS を追加してエクスポートし、インポート後に DBMS_STATS で収集する
インポート時の ORA-00959: tablespace not found エクスポート元の表領域がインポート先に存在しない REMAP_TABLESPACE=元:先 で変換するか、インポート先に同名表領域を作成する

よく使うパラメータ一覧

パラメータ 説明
SCHEMAS エクスポート/インポートするスキーマ名(カンマ区切り) SCHEMAS=hr,scott
TABLES テーブル単位の指定(スキーマ.テーブル名) TABLES=hr.employees
FULL フルデータベースのエクスポート/インポート FULL=y
DIRECTORY ダンプファイル・ログファイルの出力先 DIRECTORY 名 DIRECTORY=dp_dir
DUMPFILE ダンプファイル名(%U で連番、%date% は OS 依存) DUMPFILE=hr_%U.dmp
LOGFILE ログファイル名 LOGFILE=hr_export.log
PARALLEL 並列度(Enterprise Edition のみ) PARALLEL=4
COMPRESSION 圧縮(METADATA_ONLY / DATA_ONLY / ALL / NONE) COMPRESSION=ALL
FILESIZE ダンプファイルの最大サイズ(分割する場合は %U も指定) FILESIZE=2G
FLASHBACK_TIME 指定時刻のデータをエクスポートする(一貫したスナップショット) FLASHBACK_TIME=SYSTIMESTAMP
REMAP_SCHEMA スキーマ名を変換してインポート(impdp のみ) REMAP_SCHEMA=hr:hr_dev
REMAP_TABLESPACE 表領域名を変換してインポート(impdp のみ) REMAP_TABLESPACE=USERS:USERS_DEV
TABLE_EXISTS_ACTION 既存テーブルの扱い(impdp のみ) TABLE_EXISTS_ACTION=REPLACE
EXCLUDE / INCLUDE オブジェクト種類・名前でフィルタリング EXCLUDE=STATISTICS
CONTENT エクスポート内容(ALL / DATA_ONLY / METADATA_ONLY) CONTENT=DATA_ONLY
NETWORK_LINK DB Link 経由の直接転送(ダンプファイル不要) NETWORK_LINK=prod_link

まとめ

  • DIRECTORY オブジェクト:Data Pump はサーバーサイドで動作する。ダンプファイルの出力先はクライアント側ではなく、DBA_DIRECTORIES で管理される OS ディレクトリ。GRANT READ, WRITE で各ユーザーに権限を付与する
  • expdp の基本:SCHEMAS=スキーマ名 でスキーマ全体をエクスポート。QUERY で行フィルタリング、EXCLUDE=STATISTICS でインポート後に統計を再収集するのが一般的なベストプラクティス
  • impdp のスキーマ移行:REMAP_SCHEMA=元:先 でスキーマ名を変更、REMAP_TABLESPACE=元:先 で表領域名を変更。SQLFILE オプションでドライランして DDL を事前確認できる
  • TABLE_EXISTS_ACTION:既存テーブルがある場合の動作。SKIP(デフォルト)・APPEND(追記)・TRUNCATE(切り詰め再投入)・REPLACE(DROP→再作成)から選択する
  • NETWORK_LINK:DB Link を経由してダンプファイルなしで DB 間を直接転送できる。本番→開発のデータ同期に便利
  • 進捗確認:V$SESSION_LONGOPS で進捗率と残り時間を確認。expdp attach=ジョブ名 で実行中ジョブに接続してリアルタイムに操作できる

エクスポートしたデータの整合性確認には SCN(System Change Number)を活用できます。FLASHBACK_TIME や FLASHBACK_SCN で一貫した時点のデータをエクスポートする方法は Oracle SCN 完全ガイドを参照してください。SQL*Loader(sqlldr)を使ったデータロードは Oracle SQL*Loader 完全ガイドも参照してください。