RDS for OracleのダンプファイルをEC2に移動させたい時

# RDS for OracleのダンプファイルをEC2に移動させたい時
ネットの記事を見ながら作業を行いましたが躓いた点がいくつかあったので自分のために記事にしました


# 環境情報
OS:EC2 WindowServer2019
DB:RDS for Oracle19c

# 流れ
<!-- タイトルとアンカー名を編集 -->
1. [ダンプファイルの作成](#Chapter1)
1. [ダンプファイルの確認](#Chapter2)
1. [ダンプファイルの転送準備](#Chapter3)
1. [ダンプファイルの転送](#Chapter4)
1. [参考文献](#reference)


<!-- 各チャプター -->
<a id="#Chapter1"></a>

# ダンプファイルの作成
RDSのsqlplusからダンプを作成します
ADMIN部分はRDSを作成したときのマスターユーザーを使用して下さい
hogehoge.DMP　hogehoge.LOGは任意の名前にしてください

※下記の＜＞内は任意に変更してください
※注意
'SCHEMA_EXPR','IN (''ADMIN'')'に記載するスキーマ名は必ず大文字

```sql:ダンプファイル作成
DECLARE
hdnl NUMBER;
BEGIN
hdnl := DBMS_DATAPUMP.open( operation => 'EXPORT', job_mode => 'SCHEMA', job_name=>null);
DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => '＜hogehoge.dmp＞', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file,reusefile => 1);
DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => '＜hogehoge.log＞', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file,reusefile => 1);
DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_EXPR','IN (''＜ADMIN＞'')');
DBMS_DATAPUMP.start_job(handle => hdnl);
END;
/
```

job_modeは実行する操作の有効範囲なので状況に合わせて指定してください

FULL：Oracle Databaseの内部スキーマを除く、全データベースまたは全ダンプ・ファイル・セットで動作
SCHEMA：選択された一連のスキーマで動作
TABLE：選択された一連の表で動作
TABLESPACE：選択された一連の表領域で動作
TRANSPORTABLE：選択された一連の表領域内の表(およびその表が依存するオブジェクト)に関するメタデータで動作し、トランスポータブル表領域のエクスポートおよびインポートを実行


<a id="#Chapter2"></a>
# ダンプファイルの確認
下記コマンドを実行して先ほど作成したdmpファイルとlogファイルが存在しているか確認してください

```sql:ダンプファイルの確認
select * from table (rdsadmin.rds_file_util.listdir(p_directory => 'DATA_PUMP_DIR'));
```

<a id="#Chapter3"></a>
# ダンプファイルの転送準備
dmpファイルの移動を行うにあたってperlを使用します
なのでここではEC2環境にperlをインストールします
参考:https://www.javadrive.jp/perl/activeperl/

下記Perlファイルを作成
EC2上でテキストファイルを作成して適当なPerlファイルに名前を変えます
ここではtransfer.plとしました
※下記の＜＞内は任意に変更してください

```perl:transfer.pl
use DBI;
 
my $RDS_PORT=1521;
my $RDS_HOST="＜RDPのエンドポイント＞";
my $RDS_LOGIN="＜マスターユーザ＞/＜パスワード＞";
my $RDS_SID="＜DB名＞";
 
my $dirname = "DATA_PUMP_DIR";
my $fname   = $ARGV[0];
 
my $data  = "dummy";
my $chunk = 32767;
 
my $sql_open   = "BEGIN perl_global.fh := utl_file.fopen(:dirname,:fname,'rb',:chunk);END;";
my $sql_read   = "BEGIN utl_file.get_raw(perl_global.fh,:data,:chunk); END;";
my $sql_close  = "BEGIN utl_file.fclose(perl_global.fh); END;";
my $sql_global = "create or replace package perl_global as fh utl_file.file_type; end;";
 
my $conn = DBI->connect('dbi:Oracle:host='.$RDS_HOST.';sid='.$RDS_SID.';port='.$RDS_PORT, $RDS_LOGIN, '') || die ( $DBI::errstr . "\n") ;
 
my $updated=$conn->do($sql_global);
my $stmt = $conn->prepare($sql_open);
$stmt->bind_param_inout(":dirname", \$dirname, 12);
$stmt->bind_param_inout(":fname", \$fname, 12);
$stmt->bind_param_inout(":chunk", \$chunk, 5);
$stmt->execute() || die($DBI::errstr . "\n");
 
open(INF,"> $fname") || die "\nCan't open $fname for writing: $!\n";
binmode(INF);
 
$stmt = $conn->prepare($sql_read);
my %attrib = ('ora_type','24');
my $val=0;
while ($val==0){
    # $stmt->execute() writes ORA-1403(NO_DATA_FOUND) message to STDERR.
    # To hidden the message, do "open STDERR" at first.
    open STDERR, '>', undef;
    $stmt->bind_param_inout(":data", \$data, $chunk, \%attrib);
    $stmt->bind_param_inout(":chunk", \$chunk, 5);
    $stmt->execute();
    $val = $stmt->err;
    if($val != 0){
        if($val == 1403){ last; }
        open(STDERR, ">&STDOUT");
        die "$DBI::errstr \nProblem copying: $!\n" if $!;
    };
    print INF $data || die "\nWriting File error: $!\n";
 };
close INF || die "Can't close $fname: $!\n";
$stmt = $conn->prepare($sql_close);
$stmt->execute() || die ($DBI::errstr . "\n");
```

<a id="#Chapter4"></a>
# ダンプファイルの転送
EC2上でコマンドプロンプトを開きPerlファイルがある場所まで移動します
そこでPerlを実行してdmpファイルが作成されたらOKです

下記コマンドではPerlファイルの実行の後にどのdmpファイルを移動させるか指定する必要があります。
```:ダンプファイルの転送
C:\>perl transfer.pl hogehoge.dmp
```

# 最後に
PerlファイルにADMINユーザーやパスワード、RDSのエンドポイントを記載してしまっているので作業を行った後は削除したり、ローカル環境に移動させたりしたほうがいいかもしれません。
内容によって生じた直接的、間接的な損害に対し、一切の責任を負いかねますので、ご了承ください



<a id="#reference"></a>
# 参考文献
- [https://xp-cloud.jp/blog/2018/02/06/2955/](URL)
- [https://www.javadrive.jp/perl/activeperl/](URL)