RDS for OracleのダンプファイルをEC2に移動させたい時
ネットの記事を見ながら作業を行いましたが躓いた点がいくつかあったので自分のために記事にしました
環境情報
OS:EC2 WindowServer2019
DB:RDS for Oracle19c
流れ
ダンプファイルの作成
RDSのsqlplusからダンプを作成します
ADMIN部分はRDSを作成したときのマスターユーザーを使用して下さい
hogehoge.DMP hogehoge.LOGは任意の名前にしてください
※下記の<>内は任意に変更してください
※注意
'SCHEMA_EXPR','IN (''ADMIN'')'に記載するスキーマ名は必ず大文字
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:選択された一連の表領域内の表(およびその表が依存するオブジェクト)に関するメタデータで動作し、トランスポータブル表領域のエクスポートおよびインポートを実行
ダンプファイルの確認
下記コマンドを実行して先ほど作成したdmpファイルとlogファイルが存在しているか確認してください
select * from table (rdsadmin.rds_file_util.listdir(p_directory => 'DATA_PUMP_DIR'));
ダンプファイルの転送準備
dmpファイルの移動を行うにあたってperlを使用します
なのでここではEC2環境にperlをインストールします
参考:https://www.javadrive.jp/perl/activeperl/
下記Perlファイルを作成
EC2上でテキストファイルを作成して適当な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");
ダンプファイルの転送
EC2上でコマンドプロンプトを開きPerlファイルがある場所まで移動します
そこでPerlを実行してdmpファイルが作成されたらOKです
下記コマンドではPerlファイルの実行の後にどのdmpファイルを移動させるか指定する必要があります。
C:\>perl transfer.pl hogehoge.dmp
最後に
PerlファイルにADMINユーザーやパスワード、RDSのエンドポイントを記載してしまっているので作業を行った後は削除したり、ローカル環境に移動させたりしたほうがいいかもしれません。
内容によって生じた直接的、間接的な損害に対し、一切の責任を負いかねますので、ご了承ください