2025/06/09, 2025/09/08 Amazon RDS for Oracle19cのインスタンスに、業務アプリケーションごとにA,B,C…のように 複数のOracleスキーマ(ユーザー)があります。 バッチ処理で毎日、スキーマ単位のバックアップを取得したいとき、 レガシーのexpユーティリティと、新しいけれどもRDSではローカルファイルシステムにアクセスできないexpdp(Datapump)ユーティリティ とでは、どちらを使うのが望ましいですか? 以下の詳細条件を踏まえて比較してください。 - RDSと同じVPC内にあるAmazon EC2インスタンスにOracle Instant Client 19cをインストールして実行 - ダンプファイルはEC2のファイルシステム内に保管したい - スキーマ単位でエクスポートする - 目的は、人為ミスによるデータ破損時に、DBAの手を借りずにアプリケーション担当者がインポートで復旧作業ができるようにしたいため。 ------ ChatGPTの回答 expdpを推奨。network_linkという物を張る。 expdp user/password@tns_alias schemas=SCHEMA_A directory=dp_dir dumpfile=schema_a.dmp logfile=schema_a.log 復旧イメージ impdp user/password@tns_alias schemas=SCHEMA_A dumpfile=schema_a.dmp logfile=imp_schema_a.log ------ network_linkとは何ですか?tnsnames.oraの記述方法を教えてください。 ------ expdp admin/password@RDS_ALIAS \ network_link=RDS_ALIAS \ schemas=SCHEMA_A \ dumpfile=schema_a_20250609.dmp \ logfile=schema_a_20250609.log \ directory=DATA_PUMP_DIR_ON_EC2 ------ RDS_ALIAS = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = mydb.xxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = ORCL) ) ) ------ 上記のサンプルでは、「@localhost」の部分は常に「@localhost」で良いですか? また、RDS_DB_LINK_NAME=RDS_ALIAS ですか? ------ うーん、よく分からない。 network_linkを使うには、EC2上にもOracle Databaseを導入する必要があり、そこからDBLINKを張る必要があるという意味らしい。 ------ Claudeの回答 expを推奨。 ------ expは非推奨とのことですが、Oracle Database23aiのバージョンでは利用可能ですか。 ------ 利用不可です。 ------ 以下のexpのコマンドラインを、最も簡単にexpdpに置き換えてください。 exp userid=scott/tiger@RDSDB direct=y file=/home/appuser1/export.dmp log=/home/appuser1/export.log ------ expdp scott/tiger@RDSDB schemas=scott \ dumpfile=export.dmp \ logfile=export.log \ directory=DATA_PUMP_DIR ------ ※direct=yに当たる指定は不要。 ------ RDSのデフォルトのDATA_PUMP_DIRに出力されたexport.dmpを、 expdpコマンドを実行しているクライアントマシン上に取得するには? ------ expdp scott/tiger@EC2_TNS_ALIAS \ network_link=RDS_LINK \ schemas=scott \ dumpfile=export.dmp \ logfile=export.log \ directory=LOCAL_DIR -- EC2上で定義した仮想ディレクトリ ------ Amazon RDS for Oracleに特化して、expと同様のことができるもっと簡易なツールはありませんか? ------ 1. expdp⇒dmpをS3に転送⇒AWS CLIでEC2にcp 2. sqlcl unload 3. AWS DMSを使用したインクリメンタルバックアップ(ただしDDLの保存は不可) ------ 3のAWS DMSを使用する方法は、テーブル定義を変更するとバックアップは破棄が必要で、最初から取得し直す必要があるという意味ですか。 ⇒必ずしもそうではない。 列が減るとエラーになる。列が増えてもエラーにはならないが、Fullで取り直すまでその列は無視されてしまう。 ------ expコマンドはOracle Database 23aiからは廃止されてしまいます。代替となる良い方法は? ------ もうRDSのsnapshotを取っておけ ------ aws rds create-db-snapshot \ --db-instance-identifier your-rds-instance \ --db-snapshot-identifier ${TIMESTAMP}-schema-backup ------ SQLclでのデータ・ポンプ・サポート https://docs.oracle.com/cd/F59264_01/sqcug/data-pump.html ------ https://wisteriasec.wordpress.com/2022/06/28/oracle-database%E5%90%91%E3%81%91%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E3%81%AE%E6%96%B0%E3%81%97%E3%81%84%E5%AE%9A%E7%95%AA%EF%BC%9Fsqlcl%E3%81%8C%E3%81%A9%E3%82%8C%E3%81%8F%E3%82%89/ ------ https://qiita.com/500InternalServerError/items/c2d5734ec01a1176500f sqlclはcurlでLinuxにインストールできるらしい ------ sqlcl unloadコマンドはexpの代替として使えますか? ------ 一部はなるが制約もある。 ・テーブル単位のみ対応(スキーマ一括エクスポート不可) ・データのみの出力(DDLは別途必要) ・インデックス、制約、権限などのメタデータは含まれない なので、TABLE,INDEX,CONSTRAINTなどは DBMS_METADATA.GET_DDL 関数を使って別途出力が必要。 ------ RDS for Oracle 19c内の一つのスキーマ全体を、expコマンドで毎日エクスポートしています。 目的は、作業ミスによるデータ破損の場合に、DB管理者の手を煩わせずに、 アプリケーション運用者だけの力でデータを復旧したいためです。 ところが、expコマンドはOracle23ai以降廃止されます。代替となるよい方法はありますか? ------ expdp/impdp RDS内蔵ではなく、S3に書き出す。(Oracle Directory使用) ただしS3からのインポートはrdsadminの関数を使うため、DB管理者の作業が必須。 ------ または、DBLINKを使用したネットワークインポート impdp userid=username/password@target_rds \ network_link=SOURCE_DB_LINK \ tables=SOURCE_SCHEMA.TABLE1 \ remap_schema=SOURCE_SCHEMA:TARGET_SCHEMA \ logfile=network_import.log ------ RDSのEFS統合の仕組みを使って、EFSにdmpを出力することもできますか。 ------ 可能です。 ------ # スキーマ全体をEFSに直接エクスポート expdp userid=username/password@rds_oracle \ directory=EFS_DATAPUMP_DIR \ dumpfile=schema_backup_$(date +%Y%m%d).dmp \ logfile=export_$(date +%Y%m%d).log \ schemas=YOUR_SCHEMA \ compression=all # 特定テーブルのみEFSにエクスポート expdp userid=username/password@rds_oracle \ directory=EFS_DATAPUMP_DIR \ dumpfile=table_backup_$(date +%Y%m%d).dmp \ logfile=table_export_$(date +%Y%m%d).log \ tables=SCHEMA.TABLE1,SCHEMA.TABLE2 \ compression=all ------ impdp userid=recovery_user/password@prod_rds \ directory=EFS_DATAPUMP_DIR \ dumpfile=daily_backup_${BACKUP_DATE}_*.dmp \ logfile=recovery_${TABLE_NAME}_$(date +%Y%m%d_%H%M%S).log \ tables=APP_SCHEMA.${TABLE_NAME} \ table_exists_action=REPLACE ------ EFSファイルシステムに出力されたdmpファイルをEC2にアタッチしてlsで見ると、 パーミッションが0600になっています。 そうすると、root以外のLinuxユーザーでimpdpを実行するには、 EC2のrootユーザーがいずれかのEC2の領域にコピーしてchownする必要がありますか。 ------ いいえ、もっと効率的な方法があります。 ------ 方法1 # EFSマウント時にユーザーID/グループIDを指定 sudo mkdir -p /mnt/efs-oracle sudo mount -t efs -o tls,uid=1001,gid=1001 fs-0123456789abcdef0 /mnt/efs-oracle # fstabに永続化 echo "fs-0123456789abcdef0.efs.ap-northeast-1.amazonaws.com:/ /mnt/efs-oracle efs defaults,_netdev,tls,uid=1001,gid=1001" | sudo tee -a /etc/fstab ------ 方法2 Oracleディレクトリ作成時にumaskを022にすれば0644でファイルが作られる -- RDS側でumask設定を含むディレクトリ作成 BEGIN -- システムレベルでのumask設定 rdsadmin.rdsadmin_util.set_configuration( name => 'file_umask', value => '022' -- 644権限でファイル作成 ); -- EFS統合ディレクトリ作成 rdsadmin.rdsadmin_util.create_directory_for_efs( p_directory_name => 'EFS_SHARED_DIR', p_efs_file_system_id => 'fs-0123456789abcdef0', p_path_prefix => '/oracle/shared' ); END; / ------ 方法3: 共有グループの活用 ------ # Oracle専用グループ作成 sudo groupadd oracle-ops sudo usermod -a -G oracle-ops ec2-user sudo usermod -a -G oracle-ops oracle-app-user # EFSを共有グループでマウント sudo mount -t efs -o tls,gid=oracle-ops,fmask=0002,dmask=0002 \ fs-0123456789abcdef0 /mnt/efs-oracle ------