RDSのOracleでdumpファイルを扱う
RDS Oracleにて、dumpを扱う方法が随分簡単になっていたので、試したときのメモです。
設定
まずは利用するための設定を実施。以下が公式マニュアル。
S3Bucketの作成
dumpファイルを置くためのS3Bucketを作成しておきます。今回は oracle-dump-zunda
という名前のBucketを作成しています。
RDS用のIAM Roleの作成
dumpファイルを置くことになるS3Bucketへのアクセス権限をもった、RDS向けのIAM Roleを作成します。CloudFormationテンプレートでは、こんな感じです。
AWSTemplateFormatVersion: "2010-09-09" Description: "IAM Role for RDS Oracle Integration with Amazon S3" Resources: IamRole: # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html Type: "AWS::IAM::Role" DeletionPolicy: "Delete" Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "rds.amazonaws.com" Action: - "sts:AssumeRole" # Description: String # ManagedPolicyArns: # - String # MaxSessionDuration: Integer Path: "/role/" # PermissionsBoundary: String Policies: - PolicyName: "S3-Bucket-Access" PolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Action: - "s3:GetObject" - "s3:ListBucket" - "s3:PutObject" Resource: - "arn:aws:s3:::oracle-dump-zunda" - "arn:aws:s3:::oracle-dump-zunda/*" RoleName: "ForOracleDump" # Tags: # - Tag
RDS Option Groupの変更
RDSで利用するOption Groupに、Option S3_INTEGRATION
を追加します。
RDSインスタンスにRoleを付与
RDSインスタンスにIAM Roleを付与するには、RDSのコンソールの Connectivity & security
タブの Manage IAM roles
セクションを変更することになります。下の画面です。
dumpのエクスポート&インポート
設定は完了しましたので、実際にdumpを試してみます。以下が公式マニュアル。
Amazon RDS での Oracle へのデータのインポート
後述作業、全てRDS masteruserで接続して実行しています。
dumpのエクスポート
RDSにおいても、dump処理用のDATA_PUMP_DIRディレクトリオブジェクトが用意されており、dumpファイルにてこのOS領域を利用できます。ちなみに、DATA_PUMP_DIRディレクトリのOS上パスはこちらですが、OS層にアクセスできないRDSでは、AWS側で用意されたプロシージャを利用することになります。
> column owner format a10 > column directory_name format a20 > column directory_path format a30 > select * from dba_directories; OWNER DIRECTORY_NAME DIRECTORY_PATH ---------- -------------------- ------------------------------ SYS RDS$DB_TASKS /rdsdbdata/dbtasks SYS BDUMP /rdsdbdata/log/trace SYS ADUMP /rdsdbdata/log/audit SYS DATA_PUMP_DIR /rdsdbdata/datapump
dumpの取得には、Oracle DBに最初からIncludeされているPL/SQLの DBMS_DATAPUMP
というパッケージを利用します。dumpエクスポート処理時のジョブを作成するサンプルは、以下となります。スキーマ zunda
のdaumpファイルを、 ディレクトリ DATA_PUMP_DIR
上でにエクスポートする処理となっています。ダンプファイルのほか、処理実行時のログ・ファイルも出力しています。
DECLARE hdnl NUMBER; status VARCHAR2(20); BEGIN hdnl := DBMS_DATAPUMP.OPEN( operation => 'EXPORT', job_mode => 'SCHEMA', job_name => null ); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'zunda-20191114.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file, reusefile => 0 ); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'zunda-export-20191114.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file, reusefile => 0 ); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_EXPR','IN (''ZUNDA'')'); DBMS_DATAPUMP.START_JOB(handle => hdnl); DBMS_DATAPUMP.WAIT_FOR_JOB(handle => hdnl, job_state => status); END; /
実行されているDBMS_DATAPUMPパッケージの各プロシージャ詳細は、以下より確認できます。
なお、RDSで利用できるdumpの対象は、スキーマまたはテーブルとなります。fullモードのdumpは利用しては駄目とのこと。
特定のスキーマやオブジェクトをインポートするには、schema または table モードでインポートを実行します。
インポートするスキーマをアプリケーションに必要なスキーマに制限します。
full モードではインポートしないでください。Amazon RDS for Oracle では、管理ユーザー SYS または SYSDBA へのアクセスは許可されていないため、full モードでインポートしたり、Oracle 管理のコンポーネントのスキーマをインポートしたりすると、Oracle データディレクトリが損傷し、データベースの安定性に影響を及ぼす可能性があります。
エクスポートされたdumpファイルは、RDSにて用意された RDSADMIN.RDS_FILE_UTIL.LISTDIR
プロシージャを利用することで確認できます。
> column filename format a30 > column type format a10 > column mtime format a10 > select * from table(RDSADMIN.RDS_FILE_UTIL.LISTDIR(p_directory => 'DATA_PUMP_DIR')) order by mtime; FILENAME TYPE FILESIZE MTIME ------------------------------ ---------- ---------- ---------- datapump/ directory 4096 14-NOV-19 zunda-20191114.dmp file 188416 14-NOV-19 zunda-export-20191114.log file 967 14-NOV-19
ディレクトリオブジェクト上に存在するファイルは、RDSにて用意された RDSADMIN.RDS_FILE_UTIL.LISTDIR
プロシージャを利用することで参照することができるので、以下にて今回処理のログ・ファイルを参照可能です。
> select * from table > (rdsadmin.rds_file_util.read_text_file( > p_directory => 'DATA_PUMP_DIR', > p_filename => 'zunda-export-20191114.log')); TEXT -------------------------------------------------------------------------------- Starting "ADMIN"."SYS_EXPORT_SCHEMA_08": Estimate in progress using BLOCKS method... Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA Total estimation using BLOCKS method: 64 KB Processing object type SCHEMA_EXPORT/USER Processing object type SCHEMA_EXPORT/SYSTEM_GRANT Processing object type SCHEMA_EXPORT/ROLE_GRANT Processing object type SCHEMA_EXPORT/DEFAULT_ROLE Processing object type SCHEMA_EXPORT/TABLESPACE_QUOTA Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA Processing object type SCHEMA_EXPORT/TABLE/TABLE TEXT -------------------------------------------------------------------------------- . . exported "ZUNDA"."SAMPLE" 5.492 KB 7 rows Master table "ADMIN"."SYS_EXPORT_SCHEMA_08" successfully loaded/unloaded ****************************************************************************** Dump file set for ADMIN.SYS_EXPORT_SCHEMA_08 is: /rdsdbdata/datapump/zunda-20191114.dmp Job "ADMIN"."SYS_EXPORT_SCHEMA_08" successfully completed at Thu Nov 14 15:14:05 2019 elapsed 0 00:00:02 17 rows selected.
ディレクトリオブジェクト上のファイルは、RDSにて用意された rdsadmin.rdsadmin_s3_tasks.upload_to_s3
プロシージャを利用することで、S3へアップロードすることが可能です。以下の例は、 DATA_PUMP_DIR
にある zunda-20191114.dmp
ファイルを、 s3://oracle-dump-zunda/zunda/20191114/zunda-20191114.dmp
というS3オブジェクトしてアップロードする処理となっています。
> SELECT rdsadmin.rdsadmin_s3_tasks.upload_to_s3( > p_directory_name => 'DATA_PUMP_DIR', > p_prefix => 'zunda-20191114.dmp', > p_bucket_name => 'oracle-dump-zunda', > p_s3_prefix => 'zunda/20191114/') > AS TASK_ID FROM DUAL; TASK_ID -------------------------------------------------------------------------------- 1573713349502-624
Oracle DB インスタンスから Amazon S3 バケットにファイルをアップロードする
実行処理はBDUMディレクトリにログを出力してくれます。upload処理を実行した際にTASK_IDを返されるので、ファイル名を dbtask-(TASK_ID).log
として、以下のSQLにて確認できます。
> SELECT text FROM table( > rdsadmin.rds_file_util.read_text_file( > p_directory => 'BDUMP', > p_filename => 'dbtask-1573713349502-624.log')); TEXT -------------------------------------------------------------------------------- 2019-11-14 06:35:49.556 UTC [INFO ] File #1: Uploading the file /rdsdbdata/datap ump/zunda-20191114.dmp to Amazon S3 with bucket name oracle-dump-zunda and key z unda/20191114/zunda-20191114.dmp. 2019-11-14 06:35:49.706 UTC [INFO ] The file /rdsdbdata/datapump/zunda-20191114. dmp was uploaded to Amazon S3 with bucket name oracle-dump-zunda and key zunda/2 0191114/zunda-20191114.dmp. 2019-11-14 06:35:49.706 UTC [INFO ] The task finished successfully.
S3上にアップロードできたことを確認できた後、 DATA_PUMP_DIR
上にあるdumpファイルは削除してしまいます。削除には UTL_FILE.FREMOVE
プロシージャを利用します。
exec utl_file.fremove( location => 'DATA_PUMP_DIR', filename => 'zunda-20191114.dmp'); exec utl_file.fremove( location => 'DATA_PUMP_DIR', filename => 'zunda-export-20191114.log');
dumpのインポート
続いてdumpのインポート処理です。
S3上にあるdumpファイルは、RDSにて用意された rdsadmin.rdsadmin_s3_tasks.download_from_s3
プロシージャを利用することでRDSのディレクトリオブジェクト上にダウンロードすることができます。
> SELECT rdsadmin.rdsadmin_s3_tasks.download_from_s3( > p_bucket_name => 'oracle-dump-zunda', > p_s3_prefix => 'zunda/20191114/zunda-20191114.dmp', > p_directory_name => 'DATA_PUMP_DIR') > AS TASK_ID FROM DUAL; TASK_ID -------------------------------------------------------------------------------- 1573713541244-624
Amazon S3 バケットから Oracle DB インスタンスにファイルをダウンロードする
ダウンロードされたことを確認します。
> column filename format a30 > column type format a10 > column mtime format a10 > select * from table(RDSADMIN.RDS_FILE_UTIL.LISTDIR(p_directory => 'DATA_PUMP_DIR')) order by mtime; FILENAME TYPE FILESIZE MTIME ------------------------------ ---------- ---------- ---------- zunda-20191114.dmp file 188416 14-NOV-19 datapump/ directory 4096 14-NOV-19
dumpをぶち込む前に、既存であるスキーマを削除してしまいます。
DROP USER ZUNDA CASCADE;
DBへのインポート処理も、DBMS_DATAPUMP
パッケージを利用します。以下がサンプルとなります。
DECLARE hdnl NUMBER; status VARCHAR2(20); BEGIN hdnl := DBMS_DATAPUMP.OPEN( operation => 'IMPORT', job_mode => 'SCHEMA', job_name => null); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'zunda-20191114.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'zunda-import-20191114.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file ); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_EXPR','IN (''ZUNDA'')'); DBMS_DATAPUMP.START_JOB(handle => hdnl); DBMS_DATAPUMP.WAIT_FOR_JOB(handle => hdnl, job_state => status); END; /
実行ログを確認します。
select * from table (rdsadmin.rds_file_util.read_text_file( p_directory => 'DATA_PUMP_DIR', p_filename => 'zunda-import-20191114.log'));
dump対象のスキーマ内にあるテーブルにアクセスして、インポートされていることを確認します。最後に DATA_PUMP_DIR
上のファイルを削除しておきます。
exec utl_file.fremove( location => 'DATA_PUMP_DIR', filename => 'zunda-20191114.dmp'); exec utl_file.fremove( location => 'DATA_PUMP_DIR', filename => 'zunda-import-20191114.log');