【Oracle】別サーバーへデータベースを移行する方法|ファイル転送・DB Link・NETWORK_LINK・移行チェックリストまで解説

【Oracle】別サーバーへデータベースを移行する方法|ファイル転送・DB Link・NETWORK_LINK・移行チェックリストまで解説 Oracle

Oracle データベースの別サーバーへの移行は、バージョンアップ、クラウド移行、サーバーリプレース、開発環境の構築など多くの場面で発生します。

Oracle にはサーバー間でデータを移行する方法が複数あり、状況に応じて最適な方式が異なります。本記事では、Data Pump ファイル転送方式NETWORK_LINK(ダンプファイル不要の直接移行)DB Link + CTAS 方式の 3 パターンを比較し、移行前の事前確認実行手順移行後の検証まで体系的に解説します。

この記事でわかること
・3 つの移行方式(ファイル転送 / NETWORK_LINK / DB Link CTAS)の比較
・移行前の事前確認(文字セット / 表領域 / バージョン / ユーザー)
・Data Pump ファイル転送方式の完全手順(expdp → SCP → impdp)
・NETWORK_LINK でダンプファイルなしに直接移行する方法
・REMAP_SCHEMA / REMAP_TABLESPACE の使い方
・移行後の検証手順(件数 / オブジェクト数 / INVALID チェック)
・移行チェックリスト
スポンサーリンク

3 つの移行方式の比較

方式 手順 ダンプファイル 速度 適するケース
Data Pump ファイル転送
expdp → SCP → impdp
(1) expdp でダンプ出力
(2) SCP/SFTP でファイル転送
(3) impdp でインポート
必要(サーバー間転送) 高速(パラレル対応) 最も一般的。大規模データに対応。ネットワーク帯域を最大活用
NETWORK_LINK
impdp network_link=
移行先から impdp を実行するだけ(1 コマンド) 不要 中(ネットワーク依存) ダンプファイルの保存場所がない場合。中小規模のデータ
DB Link + CTAS
CREATE TABLE AS SELECT … @dblink
テーブルごとに CTAS で個別コピー 不要 低〜中 テーブル単位の部分移行。制約/インデックスは別途再作成
方式選択の判断基準
・大規模(数十 GB 以上)→ ファイル転送方式(パラレル + 圧縮で最速)
・中小規模 + ダンプ不要 → NETWORK_LINK(1 コマンドで完結)
・テーブル単位の部分コピー → DB Link + CTAS

移行前の事前確認

SQL(移行元で確認すべき情報)
-- (1) 文字セット
SELECT parameter, value FROM nls_database_parameters
WHERE parameter IN ('NLS_CHARACTERSET', 'NLS_NCHAR_CHARACTERSET');

-- (2) Oracle バージョン
SELECT banner FROM v$version WHERE ROWNUM = 1;

-- (3) 表領域の一覧とサイズ
SELECT tablespace_name, ROUND(SUM(bytes)/1024/1024/1024, 1) AS size_gb
FROM dba_data_files GROUP BY tablespace_name ORDER BY 1;

-- (4) スキーマのオブジェクト数
SELECT owner, object_type, COUNT(*) AS cnt
FROM dba_objects WHERE owner = 'HR'
GROUP BY owner, object_type ORDER BY cnt DESC;

-- (5) テーブル行数の概算
SELECT table_name, num_rows FROM dba_tables
WHERE owner = 'HR' ORDER BY num_rows DESC;
確認項目 不一致時の対処
文字セット 移行先も同じ文字セット(AL32UTF8 推奨)で作成。異なると文字化けの原因
Oracle バージョン 移行先が下位バージョンなら expdp に version= パラメータを指定
表領域名 異なる場合は impdp の remap_tablespace= で変換
スキーマ名 異なる場合は impdp の remap_schema= で変換
ディスク容量 移行先にダンプファイル + インポート後のデータ分の空き容量が必要

バージョンが異なる場合の注意点は「バージョンが違う DB で Data Pump を使うときの注意点」を参照してください。

方式(1): Data Pump ファイル転送(最も一般的)

ステップ(1): 移行元でエクスポート

Shell(移行元サーバーで実行)
# スキーマ全体をエクスポート(パラレル + 圧縮)
expdp system/password \
    directory=DP_DIR \
    dumpfile=migration_%U.dmp \
    logfile=migration_exp.log \
    schemas=HR \
    parallel=4 \
    compression=ALL \
    flashback_time="TO_TIMESTAMP(SYSDATE)"

# flashback_time: エクスポート中のデータ一貫性を保証

ステップ(2): ダンプファイルを移行先に転送

Shell(ファイル転送)
# SCP で転送
scp /oracle/dpdir/migration_*.dmp oracle@target-server:/oracle/dpdir/

# 大量ファイルの場合は rsync で差分転送
rsync -avz --progress /oracle/dpdir/migration_*.dmp oracle@target-server:/oracle/dpdir/

# ログファイルも転送しておくと便利
scp /oracle/dpdir/migration_exp.log oracle@target-server:/oracle/dpdir/

ステップ(3): 移行先でインポート

Shell(移行先サーバーで実行)
# 同じスキーマ名・表領域名でインポート
impdp system/password \
    directory=DP_DIR \
    dumpfile=migration_%U.dmp \
    logfile=migration_imp.log \
    schemas=HR \
    parallel=4

# スキーマ名を変更する場合
impdp system/password \
    directory=DP_DIR \
    dumpfile=migration_%U.dmp \
    logfile=migration_imp.log \
    remap_schema=HR:NEW_HR \
    remap_tablespace=USERS:NEW_USERS \
    parallel=4
ファイル転送方式が最も一般的な理由
・パラレル + 圧縮で大規模データに対応
・ダンプファイルをバックアップとしても保管できる
・ネットワーク障害でもダンプがあれば再試行可能
・移行元と移行先で同時作業せずに済む(時間差 OK)

方式(2): NETWORK_LINK(ダンプファイル不要)

NETWORK_LINK パラメータを使うと、移行先の impdp が DB Link 経由で移行元に直接接続し、ダンプファイルを作成せずにデータを移行できます。

SQL(移行先で DB Link を作成)
-- 移行先サーバーで実行: 移行元への DB Link を作成
CREATE DATABASE LINK source_link
CONNECT TO system IDENTIFIED BY source_password
USING '//source-server:1521/ORCL';

-- 接続テスト
SELECT * FROM dual@source_link;
Shell(NETWORK_LINK でインポート)
# 移行先で impdp を実行(ダンプファイルなしで直接移行)
impdp system/password \
    network_link=source_link \
    logfile=network_migration.log \
    schemas=HR \
    remap_schema=HR:HR \
    remap_tablespace=USERS:USERS

# パラレル指定も可能
impdp system/password \
    network_link=source_link \
    schemas=HR \
    parallel=4
NETWORK_LINK のメリット NETWORK_LINK のデメリット
ダンプファイルが不要(ディスク容量を節約) ネットワーク帯域に依存(大規模データでは遅い)
1 コマンドで移行完了 ネットワーク切断時にやり直しが必要
移行元に expdp を実行する必要がない 移行元の負荷が高い(直接 SELECT される)
NETWORK_LINK は中小規模(数 GB 以下)に適する
大規模データ(数十 GB 以上)ではネットワーク転送がボトルネックになり、ファイル転送方式の方が高速です。また、ネットワーク障害時に最初からやり直しになるリスクがあるため、大規模移行ではファイル転送方式を推奨します。

方式(3): DB Link + CTAS(テーブル単位)

SQL(DB Link 経由で CTAS)
-- 移行先で DB Link を使ってテーブルをコピー
CREATE TABLE employees AS
SELECT * FROM employees@source_link;

CREATE TABLE departments AS
SELECT * FROM departments@source_link;

-- 制約・インデックスは別途作成が必要
ALTER TABLE employees ADD CONSTRAINT pk_emp PRIMARY KEY (employee_id);
CREATE INDEX idx_emp_dept ON employees (department_id);

DB Link の詳細は「DB リンクの作成方法」、テーブルコピーの詳細は「テーブルをコピーする方法」を参照してください。

移行後の検証手順

SQL(移行後の検証クエリ: 移行先で実行)
-- (1) オブジェクト数の比較
SELECT object_type, COUNT(*) AS cnt
FROM all_objects WHERE owner = 'HR'
GROUP BY object_type ORDER BY object_type;
-- 移行元の結果と一致することを確認

-- (2) テーブル行数の比較
SELECT table_name, num_rows FROM all_tables
WHERE owner = 'HR' ORDER BY table_name;
-- ※ 統計情報ベースの概算値。正確にはCOUNT(*)で確認

-- (3) INVALID オブジェクトのチェック
SELECT object_name, object_type, status
FROM all_objects
WHERE owner = 'HR' AND status = 'INVALID';

-- (4) INVALID オブジェクトの再コンパイル
EXEC DBMS_UTILITY.COMPILE_SCHEMA('HR');

-- (5) 制約の状態確認
SELECT constraint_name, constraint_type, status
FROM all_constraints
WHERE owner = 'HR' AND status <> 'ENABLED'
ORDER BY table_name;
SQL(正確な行数の比較: NETWORK_LINK 利用)
-- DB Link があれば移行元と移行先を直接比較できる
SELECT 'EMPLOYEES' AS table_name,
       (SELECT COUNT(*) FROM hr.employees) AS target_count,
       (SELECT COUNT(*) FROM hr.employees@source_link) AS source_count
FROM dual
UNION ALL
SELECT 'DEPARTMENTS',
       (SELECT COUNT(*) FROM hr.departments),
       (SELECT COUNT(*) FROM hr.departments@source_link)
FROM dual;

移行後の追加作業

作業 内容 SQL / コマンド
統計情報の収集 インポート後はオプティマイザ統計が古い場合がある EXEC DBMS_STATS.GATHER_SCHEMA_STATS(‘HR’)
INVALID の再コンパイル ビュー / プロシージャが INVALID になることがある EXEC DBMS_UTILITY.COMPILE_SCHEMA(‘HR’)
シーケンスの現在値調整 シーケンスの CURRVAL が移行元と異なる場合 ALTER SEQUENCE seq INCREMENT BY N; SELECT seq.NEXTVAL FROM dual; ALTER SEQUENCE seq INCREMENT BY 1
DB Link の削除 移行用の DB Link が不要になったら削除 DROP DATABASE LINK source_link
パスワードの変更 移行時に使った一時パスワードを変更 ALTER USER hr IDENTIFIED BY new_password
権限の確認 GRANT が正しく移行されたか確認 SELECT * FROM dba_tab_privs WHERE grantee = ‘HR’

移行チェックリスト

# 段階 作業 チェック
1 事前 移行元の文字セット / バージョン / 表領域 / スキーマを確認
2 事前 移行先に DIRECTORY / ユーザー / 表領域を作成
3 事前 移行先のディスク空き容量を確認(ダンプ + データ分)
4 実行 移行元で expdp を実行
5 実行 ダンプファイルを移行先に転送(SCP / rsync)
6 実行 移行先で impdp を実行
7 検証 オブジェクト数の一致を確認
8 検証 テーブル行数の一致を確認
9 検証 INVALID オブジェクトの再コンパイル
10 検証 制約の ENABLED 状態を確認
11 検証 統計情報の収集
12 後処理 一時 DB Link / 一時パスワードの削除

実務パターン集

パターン(1): 本番 → 検証環境のコピー(スキーマ名変更あり)

Shell
# 本番でエクスポート
expdp system/password \
    directory=DP_DIR \
    dumpfile=prod_hr_%U.dmp \
    schemas=HR \
    parallel=4 \
    compression=ALL \
    flashback_time="TO_TIMESTAMP(SYSDATE)"

# SCP で転送
scp /oracle/dpdir/prod_hr_*.dmp oracle@test-server:/oracle/dpdir/

# 検証環境でインポート(スキーマ + 表領域を変更)
impdp system/password \
    directory=DP_DIR \
    dumpfile=prod_hr_%U.dmp \
    remap_schema=HR:TEST_HR \
    remap_tablespace=USERS:TEST_TS \
    parallel=4

パターン(2): NETWORK_LINK で小規模 DB を直接移行

Shell
# 移行先で DB Link を作成
# CREATE DATABASE LINK src CONNECT TO system IDENTIFIED BY pw USING '//src:1521/DB';

# 移行先で 1 コマンドで移行
impdp system/password \
    network_link=src \
    schemas=HR,SALES \
    remap_tablespace=USERS:LOCAL_TS

パターン(3): クラウド移行(オンプレミス → OCI / AWS RDS)

Shell
# (1) オンプレミスでエクスポート
expdp system/password \
    directory=DP_DIR \
    dumpfile=cloud_migration_%U.dmp \
    full=y \
    parallel=8 \
    compression=ALL

# (2) ダンプをクラウドストレージに転送
# OCI: oci os object put --bucket-name migration ...
# AWS: aws s3 cp cloud_migration_*.dmp s3://bucket/

# (3) クラウド DB でダンプをダウンロードしてインポート
# OCI DBCS / AWS RDS では Data Pump の DIRECTORY 設定が必要
# 各クラウドのドキュメントに従って設定

よくある質問

Qファイル転送方式と NETWORK_LINK はどちらが速いですか?
A一般的にはファイル転送方式の方が高速です。ファイル転送方式は expdp のパラレル + 圧縮でダンプを高速に作成し、SCP/rsync でネットワーク帯域を最大限使えます。NETWORK_LINK は SQL*Net 経由で行単位のデータ転送になるため、大規模データではオーバーヘッドが大きくなります。
QNETWORK_LINK で parallel は使えますか?
A使えますimpdp ... network_link=link parallel=4 のように指定できます。ただしファイル転送方式ほどの並列効果は期待できない場合があります。
Q移行元と移行先で文字セットが異なるとどうなりますか?
A文字セットが異なると、データの文字化けやインポートエラーが発生する可能性があります。移行先の文字セットが移行元のスーパーセット(例: JA16SJIS → AL32UTF8)であれば通常は問題ありませんが、逆方向(AL32UTF8 → JA16SJIS)では文字が失われることがあります。移行先は AL32UTF8 で統一するのが安全です。
Q移行元と移行先で Oracle バージョンが異なる場合は?
A移行先が同じまたは上位バージョンであれば基本的に問題ありません。移行先が下位バージョンの場合は、expdp に version= パラメータを指定して下位互換のダンプを作成します。詳細は「バージョンが違う DB での注意点」を参照。
Q移行中にアプリケーションを停止する必要がありますか?
Aエクスポート自体はオンライン(DB 稼働中)で実行可能ですが、エクスポート中にデータが変更されると一貫性が保証されない場合があります。flashback_time パラメータを指定すれば一貫性のあるスナップショットが取得できます。最も安全なのはアプリケーションを停止してからエクスポートする方法です。
QPUBLIC シノニムや DB Link は移行されますか?
Aschemas= モードでは PUBLIC シノニムは移行されません(SYS 所有のため)。DB Link もパスワード情報の関係で移行されません。これらは移行後に手動で再作成する必要があります。full=y モードであれば PUBLIC シノニムも含まれます。

まとめ

別サーバーへの DB 移行の要点をまとめます。

やりたいこと 推奨方式
大規模データの移行(数十 GB 以上) Data Pump ファイル転送(expdp → SCP → impdp + parallel + compression)
中小規模 + ダンプファイル不要 NETWORK_LINK(impdp network_link=…)
テーブル単位の部分コピー DB Link + CTAS
スキーマ名を変更して移行 remap_schema=OLD:NEW
表領域名を変更して移行 remap_tablespace=OLD:NEW
下位バージョンへの移行 expdp version=12.2(移行先バージョンを指定)
移行後の検証 オブジェクト数 / 行数 / INVALID / 制約 / 統計を確認

Data Pump の基本は「Data Pump の使い方完全ガイド」、スキーマ単位の操作は「スキーマ単位にエクスポート・インポート」、DB Link は「DB リンクの作成方法」も併せて参照してください。