RDS for Oracle でネットワークインポートを試してみる

2021年11月26日

前回の記事「DBMS_FILE_TRANSFER を利用したデータベース間のファイル転送」では本番環境とテスト環境のデータベース間でファイルを転送しました。ですが、もし目的が「現時点の本番環境のデータをテスト環境にインポートする」ということであれば、ダンプファイルさえ作成せずに行うことができます。今回はその方法をご紹介します。タイトルには「RDS for Oracle」と書いてますが、別にオンプレ Oracle でも同じです。尚、利用するのは、Oracle 標準のインポートユーティリティである impdp コマンドです。

はじめに

冒頭に書いた「本番環境のデータをテスト環境のデータにコピーする」を想定するなら、通常は以下のような手順を考えると思います。

  1. 本番環境で expdp でエクスポートする。
  2. 上記 1. で作成されたダンプファイルをテスト環境に移動する。
  3. テスト環境で上記 2. で移動したダンプファイルを impdp でインポートする。

もちろん、上記 1. が前日のものだったり、全く別の場所に保管されていたものであればその通りです。ですが「まさに現時点の状態をコピーしたい」ということであれば impdp の NETWORK_LINK オプションを使ってインポート(ネットワークインポート)すればダンプファイルさえ作成されませんので、色々な意味で効率が良いです。

もっとも、マニュアルを見ればわかりますが、それなりに制限事項はあるので、専ら CONTENT=DATA_ONLY なインポートとかで利用するのがよろしいかとは思います。

シナリオ

前回記事と被るところはあるのですが、以下のようなシナリオとします。

  • 2つのデータベースはいずれも RDS for Oracle とする
  • ひとつを本番環境(データベース名:ORCL)、もうひとつをテスト環境(データベース名:TESTDB)とする
  • 本番環境の SCOTT スキーマのデータをテスト環境の SCOTT_TEST にコピーする。
  • 作業ミス防止のためテスト環境から本番環境へのコピーはできないようにする。

ネットワークインポート専用ユーザを作成する

まず、本番環境(データベース名:ORCL)にてネットワークインポートをするための専用ユーザを作成します。ユーザ名は “NWIMPUSER" とします。本番環境側は、エクスポートができないといけないので EXP_FULL_DATABASE 権限を付与します。

CREATE USER NWIMPUSER IDENTIFIED BY ********;
GRANT CONNECT,SELECT ANY DICTIONARY TO NWIMPUSER;
GRANT EXP_FULL_DATABASE TO NWIMPUSER;

データベースリンクを作成する

次に、テスト環境(データベース名:TESTDB)にて本番環境(データベース名:ORCL)に接続するためのデータベースリンク(NWIMP_ORCL)を作成します。エンドポイントは伏字(#)にしています。

CREATE DATABASE LINK NWIMP_ORCL
  CONNECT TO NWIMPUSER IDENTIFIED BY ********
    USING 'orcl.#####.#####.rds.amazonaws.com:1521/ORCL';

動作確認は省略しますが、必ず実施するようにしてください。

インポート先ユーザを作成する

シナリオに書きましたが、インポート先のスキーマは敢えて変更しています。 テスト環境(データベース名:TESTDB) にユーザ SCOTT_TEST を作成します。

CREATE USER SCOTT_TEST IDENTIFIED BY ********;
GRANT CONNECT,RESOURCE,UNLIMITED TABLESPACE TO SCOTT_TEST;

ネットワークインポートを行う

テスト環境(データベース名:TESTDB)本番環境(データベース名:ORCL)のいずれにも接続できる端末(EC2 でも Workspace でも VPN 接続した自宅PC 等)に Oracle Client をインストールしておきます。注意としては、データベースのバージョンを合わせることです。従来の exp / imp であれば、クライアントのバージョンが高いのは問題なかったのですが、expdp / impdp の場合は以下のエラーになります。VERSION オプションとかの関係ではなく、単純に同じバージョンじゃないとダメみたいですね。

UDI-00018: データ・ポンプ・クライアントはデータベース・バージョン12.1.0.2.0と互換性がありません

impdp が入っているインスタントクライアントを利用すれば問題ないのですが、今回利用している RDS が無償枠である関係で Oracle のバージョンは 12.1.0 です。この記事に書きましたが、impdp が入ったインスタントクライアントは 12.2.0 からしか存在しません。しかも、12.1.0 の Oracle Client はダウンロードできません。たまたま同バージョンの Client を持っていたので、それをインストールしました。

さて本題に戻ると、impdp に利用するパラメータファイル"nwimp.par"は以下の通りです。パラメータは最後で少し解説します。

SCHEMAS=SCOTT
DIRECTORY=DATA_PUMP_DIR
LOGFILE=NWIMP.LOG
REMAP_SCHEMA=SCOTT:SCOTT_TEST
NETWORK_LINK=NWIMP_ORCL
EXCLUDE=USER
EXCLUDE=SYSTEM_GRANT
EXCLUDE=ROLE_GRANT

実行するコマンドは以下の通り。コマンドプロンプトから実行しました。作成したパラメータファイルを parfile オプションで指定します。

impdp admin/********@testdb.#####.#####.rds.amazonaws.com:1521/testdb parfile=nwimp.par

実行結果のログは DATA_PUMP_DIR 上に出力されていますので以下の SQL で参照できます。

SELECT * FROM TABLE(RDSADMIN.RDS_FILE_UTIL.READ_TEXT_FILE('DATA_PUMP_DIR','NWIMP.LOG'));
ネットワークインポートのログを参照

きちんと別名でインポートできているようです。

ここでパラメータファイルにある EXCLUDE について少し補足します。これらを設定しないでインポートした場合、以下のようなエラーが発生します。(ログから抜粋)

オブジェクト型SCHEMA_EXPORT/TABLE/TABLE_DATAの処理中です
BLOCKSメソッドを使用した見積り合計: 192 KB
オブジェクト型SCHEMA_EXPORT/USERの処理中です
ORA-31684: オブジェクト型USER:"SCOTT_TEST"はすでに存在します
オブジェクト型SCHEMA_EXPORT/SYSTEM_GRANTの処理中です
ORA-31685: 権限が不十分なため、オブジェクト型SYSTEM_GRANT:"SCOTT_TEST"が失敗しました。エラー文は次のとおりです:
GRANT UNLIMITED TABLESPACE TO "SCOTT_TEST"
オブジェクト型SCHEMA_EXPORT/ROLE_GRANTの処理中です
ORA-31685: 権限が不十分なため、オブジェクト型ROLE_GRANT:"SCOTT_TEST"が失敗しました。エラー文は次のとおりです:
 GRANT "DBA" TO "SCOTT_TEST"
オブジェクト型SCHEMA_EXPORT/DEFAULT_ROLEの処理中です

上記のうち「ORA-31684: オブジェクト型USER:"SCOTT_TEST"はすでに存在します」はべつに問題ないですよね。なんたって実際に先に作ってますから。ただ、そのあとの GRANT の失敗(ORA-31685)はよくわかりません。インポートしているユーザは RDS の中では一番強い権限を持つ admin ですから、権限が不十分って、、、実際、SQL で GRANT 文を打って普通に実行できるわけですし。

実は、これ Google 先生では解決できませんでした、、(笑)きっと、RDS ならではなのでしょう、、、とか言いながら、そもそも CREATE USER も GRANT も先にやるわけですから、EXCLUDE パラメータつけておけばいいじゃん、、というのが私の結論ということです、、、、