[AWS] RDS for Oracle へ Data Pump インポートするときの DBMS_DATAPUMP パッケージオプション
こんにちは、菊池です。
まずは、こちらをご覧ください。
Oracle Databaseのデータをインポート/エクスポートするツール、Data Pumpを使ったRDS間でデータ移行を紹介しています。
マネージドサービスであるRDSでは、Data Pumpの一般的なコマンドであるimpdbを使ったインポートが利用できません。そのため、DBMS_DATAPUMPパッケージを利用しインポートを実行する必要があります。
DBMS_DATAPUMPパッケージを使ってインポートする際に指定可能なオプションを紹介します。
DBMS_DATAPUMP パッケージを使ったインポート
フルインポート
まずは基本的なフルインポートのコマンドです。
DECLARE hdnl NUMBER; BEGIN hdnl := dbms_datapump.open (operation => 'IMPORT', job_mode => 'FULL', version => 'COMPATIBLE'); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'import.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.ADD_FILE(handle => hdnl, filename => 'dumpfile.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.START_JOB(handle => hdnl); end; /
前提として、インポートするダンプファイルdumpfile.dmp
がディレクトリオブジェクトDATA_PUMP_DIR
にあることが必要です。また、インポート実行時のログ出力としてimport.log
を指定しています。
スキーマを指定したインポート
次に、スキーマを指定したインポートです。job_mode
にSCHEMA
を指定します。インポート対象のスキーマはMETADATA_FILTER
プロシージャで指定します。(この場合はSCHEMA_1、SCHEMA_2が対象になります)
DECLARE hdnl NUMBER; BEGIN hdnl := dbms_datapump.open (operation => 'IMPORT', job_mode => 'SCHEMA', version => 'COMPATIBLE'); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'import.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.ADD_FILE(handle => hdnl, filename => 'dumpfile.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_LIST',' ''SCHEMA_1'',''SCHEMA_2'' '); DBMS_DATAPUMP.START_JOB(handle => hdnl); end; /
ジョブの完了を待機
DBMS_DATAPUMPパッケージを実行が正常に終了しても、それはあくまでPL/SQLの実行が正常終了しただけで、インポートジョブは継続している場合があります。インポートジョブの完了を待って応答を返す場合には、WAIT_FOR_JOB
プロシージャを使用します。
DECLARE hdnl NUMBER; status VARCHAR2(20); BEGIN hdnl := dbms_datapump.open (operation => 'IMPORT', job_mode => 'SCHEMA', version => 'COMPATIBLE'); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'import.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.ADD_FILE(handle => hdnl, filename => 'dumpfile.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_LIST',' ''SCHEMA_1'',''SCHEMA_2'' '); DBMS_DATAPUMP.START_JOB(handle => hdnl); DBMS_DATAPUMP.WAIT_FOR_JOB(hdnl,status); end; /
統計情報を除外してインポート
11gのダンプデータを12cにインポートする場合など、互換性の問題で統計情報のインポートでエラーが発生することがあります。統計情報はインポート後に再作成することで問題ない場合には、統計情報を除外してインポートすることで余計なエラーを抑止できます。
以下ではMETADATA_FILTER
でTABLE_STATISTICS
を除外しています。
DECLARE hdnl NUMBER; status VARCHAR2(20); BEGIN hdnl := dbms_datapump.open (operation => 'IMPORT', job_mode => 'SCHEMA', version => 'COMPATIBLE'); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'import.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.ADD_FILE(handle => hdnl, filename => 'dumpfile.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_LIST',' ''SCHEMA_1'',''SCHEMA_2'' '); DBMS_DATAPUMP.METADATA_FILTER(hdnl, 'EXCLUDE_PATH_EXPR', 'IN (''TABLE_STATISTICS'')'); DBMS_DATAPUMP.START_JOB(handle => hdnl); DBMS_DATAPUMP.WAIT_FOR_JOB(hdnl,status); end; /
テーブルを指定してインポート
続いて、テーブル単位でのインポートです。job_modeはTABLEを指定します。
対象のテープルは、METADATA_FILTER
プロシージャを2回使って、スキーマを指定した上でテーブルを指定します。この場合、スキーマに指定できるのは1つのみになります。以下ではSCHEMA_1のテーブルTABLE_1とTABLE_2を指定しています。
DECLARE hdnl NUMBER; status VARCHAR2(20); BEGIN hdnl := dbms_datapump.open (operation => 'IMPORT', job_mode => 'TABLE', version => 'COMPATIBLE'); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'import.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.ADD_FILE(handle => hdnl, filename => 'dumpfile.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_LIST',' ''SCHEMA_1'' '); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'NAME_LIST',' ''TABLE_1'',''TABLE_2'' ', 'TABLE'); DBMS_DATAPUMP.START_JOB(handle => hdnl); DBMS_DATAPUMP.WAIT_FOR_JOB(hdnl,status); end; /
REMAPの指定
METADATA_REMAP
プロシージャを使うことで、移行元と異なるスキーマや表領域を指定してインポートが可能です。
以下では、移行元で表領域TABLESPACE_1にあったオブジェクトをTABLESPACE_2にインポートしています。
DECLARE hdnl NUMBER; status VARCHAR2(20); BEGIN hdnl := dbms_datapump.open (operation => 'IMPORT', job_mode => 'SCHEMA', version => 'COMPATIBLE'); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'import.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.ADD_FILE(handle => hdnl, filename => 'dumpfile.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_LIST',' ''SCHEMA_1'',''SCHEMA_2'' '); DBMS_DATAPUMP.METADATA_FILTER(hdnl, 'EXCLUDE_PATH_EXPR', 'IN (''TABLE_STATISTICS'')'); DBMS_DATAPUMP.METADATA_REMAP(hdnl, 'REMAP_TABLESPACE', 'TABLESPACE_1', 'TABLESPACE_2'); DBMS_DATAPUMP.START_JOB(handle => hdnl); DBMS_DATAPUMP.WAIT_FOR_JOB(hdnl,status); end; /
上記ではREMAP_TABLESPACE
で表領域を指定してますが、REMAP_SCHEMA
、REMAP_TABLE
といったオプションも利用できます。
既存テーブルが存在する場合の動作を指定
インポート時に同名のテーブルがすでに存在した場合、その表に対しどのようなアクションをとるか指定が可能です。
SET_PARAMETER
オプションのTABLE_EXISTS_ACTION
で指定します。スキーマモードでのデフォルトはSKIP
なので、その表へのロードはスキップされますが、以下のようにTRUNCATE
と指定することで表をTRUNCATEした上でロードすることもできます。
DECLARE hdnl NUMBER; status VARCHAR2(20); BEGIN hdnl := dbms_datapump.open (operation => 'IMPORT', job_mode => 'SCHEMA', version => 'COMPATIBLE'); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'import.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.ADD_FILE(handle => hdnl, filename => 'dumpfile.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.SET_PARAMETER(hdnl,'TABLE_EXISTS_ACTION','TRUNCATE'); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_LIST',' ''SCHEMA_1'',''SCHEMA_2'' '); DBMS_DATAPUMP.START_JOB(handle => hdnl); DBMS_DATAPUMP.WAIT_FOR_JOB(hdnl,status); end; /
他にREPLACE
、APPEND
が指定できます。
まとめ
以上です。
うまくオプションを組み合わせることで、移行戦略に合わせたインポートが可能になります。impdbコマンドでは簡単にオプション指定が可能ですが、RDSではDBMS_DATAPUMPを使う必要があります。各プロシージャを使った実行例を紹介しました。