データベース・サーバー間のファイル転送
データベース・サーバー間でファイルを転送したい場合が時々あります。Data Pump のダンプ・ファイルのコピーを行う場合などです。
scp コマンド等を使っても良いのですが、Oracle Database 10g 以降であれば、DBMS_FILE_TRANSFER パッケージを使うことで PL/SQL プログラム内からファイルの転送を行うことができます。
この方法を使うことで、オペレーティング・システムに対するファイル・アクセスが制限されているパブリック・クラウド内のマネージド・データベース間(Amazon RDSなど)でも、ファイルの転送を行うことができます。
DBMS_FILE_TRANSFER パッケージを使う場合、以下の条件でファイル転送を行うことができます。
- ファイルのコピー元、コピー先のディレクトリには DIRECTORY オブジェクトを使う。
- コピー先とコピー元は DATABASE LINK オブジェクトによる認証を行う。
- コピー元ユーザーは、コピー元 DIRECTORY に対する READ 権限、コピー先ユーザー(DATABASE LINK接続ユーザー)は、コピー先 DIRECTORY に対する WRITE 権限が必要。
- リモート・データベースに対するファイルの作成、リモート・データベースからのファイルのコピー、ローカル・データベース内のコピーができる。
- ファイル名の大文字/小文字は変換されない
ただし、ファイルであれば何でもコピーできるわけではなく、以下の制約があります。
- ファイルのサイズは 512 バイトの倍数であること
- ファイルのサイズの上限は 2 TB 以下
DBMS_FILE_TRANSFER パッケージ
DBMS_FILE_TRANSFER パッケージには以下のプロシージャが定義されています。
-
COPY_FILE
ローカル・データベース内のファイル・コピー -
GET_FILE
リモート・データベース上のファイルを、ローカル・データベースにコピーする -
PUT_FILE
ローカル・データベース上のファイルをリモート・データベースにコピーする
準備
ここでは PUT_FILE プロシージャを使って、ローカル・データベース(O12R2A)に接続して、ローカル・データベースから、リモート・データベース(O12R2B)に対してファイルを転送する処理を行います。
まず転送データを作成します。下記の例では Data Pump ユーティリティのダンプ・ファイル(scott.dmp)を作成しています。
DIRECTORYオブジェクトは、標準の DATA_PUMP_DIR を使います。
$ expdp userid=SYSTEM/password SCHEMAS=scott DIRECTORY=DATA_PUMP_DIR DUMPFILE=scott.dmp
Export: Release 12.2.0.1.0 - Production on 火 2月 5 12:37:18 2019
Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved.
接続先: Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
"SYSTEM"."SYS_EXPORT_SCHEMA_01"を起動しています: userid=SYSTEM/******** SCHEMAS=scott DIRECTORY=DATA_PUMP_DIR DUMPFILE=scott.dmp
オブジェクト型SCHEMA_EXPORT/TABLE/TABLE_DATAの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICSの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICSの処理中です
オブジェクト型SCHEMA_EXPORT/STATISTICS/MARKERの処理中です
オブジェクト型SCHEMA_EXPORT/USERの処理中です
オブジェクト型SCHEMA_EXPORT/SYSTEM_GRANTの処理中です
オブジェクト型SCHEMA_EXPORT/ROLE_GRANTの処理中です
オブジェクト型SCHEMA_EXPORT/DEFAULT_ROLEの処理中です
オブジェクト型SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMAの処理中です
オブジェクト型SCHEMA_EXPORT/SEQUENCE/SEQUENCEの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/TABLEの処理中です
オブジェクト型SCHEMA_EXPORT/PROCEDURE/PROCEDUREの処理中です
オブジェクト型SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDUREの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/INDEXの処理中です
オブジェクト型SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINTの処理中です
. . "SCOTT"."EMPLOYEES" 114.2 MB 8000000行がエクスポートされました
マスター表"SYSTEM"."SYS_EXPORT_SCHEMA_01"は正常にロード/アンロードされました
******************************************************************************
SYSTEM.SYS_EXPORT_SCHEMA_01に設定されたダンプ・ファイルは次のとおりです:
/u01/app/oracle/admin/O12R2A/dpdump/scott.dmp
ジョブ"SYSTEM"."SYS_EXPORT_SCHEMA_01"が火 2月 5 12:38:25 2019 elapsed 0 00:00:56で正常に完了しました
ファイルが作成されたことを確認します。
$ sqlplus / as sysdba
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
に接続されました。
SQL> SELECT DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME='DATA_PUMP_DIR';
DIRECTORY_PATH
--------------------------------------------------------------------------------
/u01/app/oracle/admin/O12R2A/dpdump/
SQL>
SQL> !ls -l /u01/app/oracle/admin/O12R2A/dpdump/
合計 117432
-rw-r----- 1 oracle oinstall 118 12月 21 10:53 dp.log
-rw-r--r-- 1 oracle asmadmin 2227 2月 5 12:38 export.log
-rw-r----- 1 oracle asmadmin 120242176 2月 5 12:38 scott.dmp
次にデータ転送用にリモート・データベースに接続する DATABASE LINK オブジェクトを作成します。
$ sqlplus / as sysdba
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
に接続されました。
SQL> CREATE PUBLIC DATABASE LINK REMOTE_DL1 CONNECT TO SYSTEM IDENTIFIED BY password USING 'O12R2B';
データベース・リンクが作成されました。
転送先データベースでも DIRECTORY オブジェクトが存在することを確認します。
SQL> SELECT DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME='DATA_PUMP_DIR';
DIRECTORY_PATH
--------------------------------------------------------------------------------
/u01/app/oracle/admin/O12R2B/dpdump/
ファイル転送の実行
PUT_FILE プロシージャを実行します。以下のパラメーターを指定します。
パラメーター名 | データ型 | 説明 |
---|---|---|
SOURCE_DIRECTORY_OBJECT | VARCHAR2 | コピー元 DIRECTORY オブジェクト名 |
SOURCE_FILE_NAME | VARCHAR2 | コピー元ファイル名 |
DESTINATION_DIRECTORY_OBJECT | VARCHAR2 | コピー先DIRECTORY オブジェクト名 |
DESTINATION_FILE_NAME | VARCHAR2 | コピー先ファイル名 |
DESTINATION_DATABASE | VARCHAR2 | コピー先データベースに接続する DATABASE LINK 名 |
SQL> BEGIN
2 DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
3 END;
4 /
PL/SQLプロシージャが正常に完了しました。
SQL>
転送先データベースで、ファイルが存在するか確認します。
SQL> SELECT DIRECTORY_PATH FROM DBA_DIRECTORIES WHERE DIRECTORY_NAME='DATA_PUMP_DIR';
DIRECTORY_PATH
--------------------------------------------------------------------------------
/u01/app/oracle/admin/O12R2B/dpdump/
SQL> !ls -l /u01/app/oracle/admin/O12R2B/dpdump/
合計 117428
-rw-r----- 1 oracle asmadmin 118 2月 5 11:55 dp.log
-rw-r----- 1 oracle asmadmin 120242176 2月 5 12:41 scott_dst.dmp
エラー発生
PUT_FILEプロシージャを実行する際に発生する可能性があるエラーをいくつか再現します。
TNS識別子が存在しない
tnsnames.ora ファイルに記述された接続子名を間違えた場合のエラー。
SQL> BEGIN
2 DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL2');
3 END;
4 /
BEGIN
*
行1でエラーが発生しました。:
ORA-02019: 指定されたリモート・データベースは存在しません。 ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2
転送元 DIRECTORY が存在しない場合
source_directory_object パラメーターに指定した DIRECTORY オブジェクトが存在しない場合のエラー
SQL> BEGIN
2 DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR1', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
3 END;
4 /
BEGIN
*
行1でエラーが発生しました。:
ORA-06564: オブジェクトDATA_PUMP_DIR1は存在しません。 ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2
転送先 DIRECTORY が存在しない場合
destination_directory_object パラメーターに指定した DIRECTORY オブジェクトが存在しない場合のエラー
SQL> BEGIN
2 DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR2', 'scott_dst.dmp', 'REMOTE_DL1');
3 END;
4 /
BEGIN
*
行1でエラーが発生しました。:
ORA-06564: オブジェクトDATA_PUMP_DIR2は存在しません。 ORA-02063:
先行のエラー・メッセージを参照してくださいline(REMOTE_DL1)。 ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2
転送元ファイルが存在しない場合
source_file_name パラメーターに指定されたファイルが存在しない場合のエラー。
SQL> BEGIN
2 DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp2', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
3 END;
4 /
BEGIN
*
行1でエラーが発生しました。:
ORA-19505:
ファイル"/u01/app/oracle/admin/O12R2A/dpdump/scott.dmp2"の識別に失敗しました。 ORA-27037:
ファイル・ステータスを取得できません。 Linux-x86_64 Error:
2: No such file or directory
Additional information: 7
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2
書込み先にファイルが存在する
転送先ディレクトリに既に同名のファイルが存在する場合のエラー
SQL> BEGIN
2 DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
3 END;
4 /
BEGIN
*
行1でエラーが発生しました。:
ORA-19504:
ファイル"/u01/app/oracle/admin/O12R2B/dpdump/scott_dst.dmp"の作成に失敗しました
。
ORA-27038: 作成したファイルはすでに存在します Additional
information: 1
ORA-02063: 先行のエラー・メッセージを参照してください3 lines(REMOTE_DL1)。 ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2
転送先データベース・インスタンスが停止している
転送先データベース・インスタンスまたはリスナー等が停止している場合のエラー。
SQL> BEGIN
2 DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
3 END;
4 /
BEGIN
*
行1でエラーが発生しました。:
ORA-03150: データベース・リンクの通信チャネルでend-of-fileが検出されました ORA-02063:
先行のエラー・メッセージを参照してくださいline(REMOTE_DL1)。 ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2
SQL> BEGIN
2 DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
3* END;
SQL> /
BEGIN
*
行1でエラーが発生しました。:
ORA-12514: TNS:
リスナーは接続記述子でリクエストされたサービスを現在認識していません ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2
SQL> BEGIN
2 DBMS_FILE_TRANSFER.PUT_FILE('DATA_PUMP_DIR', 'scott.dmp', 'DATA_PUMP_DIR', 'scott_dst.dmp', 'REMOTE_DL1');
3* END;
SQL> /
BEGIN
*
行1でエラーが発生しました。:
ORA-12541: TNS: リスナーがありません ORA-06512:
"SYS.DBMS_FILE_TRANSFER", 行76
ORA-06512: "SYS.DBMS_FILE_TRANSFER", 行184
ORA-06512: 行2