sorta kinda...

主にAWS関連ですが、これに限らずいろいろ勉強したことや思ったことを書いていきます。

RDS for Oracle で Data Pump による運用の形を考えてみた

シンプルな運用が大好きです、那須です。

RDS は皆さん使ってますか? OS 周りのことは気にせずに運用できるのがすごくいいですよね! そんな RDS ですが、バックアップはスナップショットがあるのであんまり自分で気にすることはありません。 ですがスナップショットからリストアすると新しいインスタンスができる形になるので、オンプレでの DB 運用を想像してるといろんなことを気にしないといけないですよね? DNS とか。 今回はそんな RDS のバックアップリストアのお話です(すいません、スナップショットの話はこれで終わりですw

 

RDS for Oracle のバックアップリストア運用パターン

RDS for Oracle では Data Pump を使ってデータのエクスポート/インポートができます。 訳あって既存の Data Pump でのバックアップリストア運用をしたくて、ちょっと調べてみました。 ちなみに RDS for Oracle へのデータインポートは↓このドキュメントが参考になりますよ。

docs.aws.amazon.com

手段は固まったのであとはどうバックアップデータを運用するかですが、RDS では下記のような形になると思います。 ダンプファイルは最終的には S3 に保存したいというのが要件です。

f:id:nasrinjp1:20190617204205p:plain

  1. エクスポート実行したら S3 にダンプファイルコピー
  2. エクスポート実行したらダンプファイルを EBS ボリュームに保存しそのボリュームのスナップショットを取る
  3. エクスポート実行したら直接 S3 バケットにコピー

もうこれ、案 3 の一択ですね!

案 1 はいちいちダンプファイルを EC2 インスタンスが中継しないといけないのでファイルサイズがでかいとその分時間もかかりますね。 S3 にダンプファイルを置かないのであればこの案もアリかなと思いますが、それだと案 2 と同じです(結局 EBS スナップショットは定期的に取るでしょうし

案 2 はネットワークコピーは RDS と EC2 インスタンス間だけですが、リストア時にスナップショットから EBS ボリュームに戻して EC2 インスタンスにアタッチしたり、実データを取ってくるために EBS ボリュームの初期化をしたりしてなんやかんや時間がかかります。 運用でのアクションが一番多いのもこのやり方です。 オペミスが怖いのであんまりやりたくありません。

対して、案 3 は中継となる EC2 インスタンスもいらないしリストアも S3 からすぐにダンプファイルを取ってこれるので、運用タスクも一番少なくてシンプルでいいですね! 時間も最短、かつ sqlplus でコマンド実行するだけで実現できるので運用負荷も少なくてすみそうです。

しかし良さそうと思って検証もせずに実装するとろくな目に合わないので、ちゃんと検証してみました。

 

実際にやってみたらちょっとだけハマった

設定の流れはクラスメソッドさんがブログで書いてくれていますので、↓を見てください(マジでいつもお世話になっております

dev.classmethod.jp

ちなみに必要な設定や運用で使うであろうコマンドたちは AWS ドキュメントに書かれています。

docs.aws.amazon.com

さあ設定もできたし、実際にエクスポートしたダンプファイルを S3 にアップロードしてみましょう。 こんなコマンドでアップロードします。

SQL> SELECT rdsadmin.rdsadmin_s3_tasks.upload_to_s3(
p_bucket_name => 'bucket_name',
p_prefix => '',
p_s3_prefix => 's3_prefix/',
p_directory_name => 'DATA_PUMP_DIR')
AS TASK_ID FROM DUAL;

結果を見てみましょう。

SQL> SELECT text FROM table(rdsadmin.rds_file_util.read_text_file('BDUMP','dbtask-xxxxxxxxxxxx-xx.log'));
 :
[ERROR] RDS doesn't have permission to write to Amazon S3 bucket name bucket_name and key s3_prefix/test.dmp.

あれ?おかしいな。 IAM ポリシーも RDS のオプショングループも AWS ドキュメント通りに設定したはずなのに、まだ権限が足らないと出ました。 もうちょっと詳しくエラー内容が出てればいいんですが、何度やってもこの文言しか出なかったので何が足りないのかこれだとわかりませんね。

ここで活躍するのが CloudTrail です。 当該時刻前後でフィルタしてみると、

User: arn:aws:sts::123456789012:assumed-role/Role_name/dbi-role-mem-id-xxxx is not authorized to perform: kms:GenerateDataKey on resource: arn:aws:kms:ap-northeast-1:123456789012:key/xxxxx

というアクセス拒否のエラーログが出てきました。 KMS 関連のエラーですね。

ふと思い出したのですが、対象の S3 バケットにはカスタマ管理 CMK を使った暗号化設定がしてあります。 なのでデータキーを取り出してそのデータキーを復号化しないといけません。 ↓のページが参考になりました。

aws.amazon.com

なので、RDS にアタッチする IAM ロールのポリシーは↓こんな感じで KMS 関連のアクションも許可しましょう。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::bucket_name",
                "arn:aws:s3:::bucket_name/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:GenerateDataKey",
                "kms:Decrypt"
            ],
            "Resource": "*"
        }
    ]
}

これで RDS for Oracle と S3 バケット間でダンプファイルの転送ができるようになりました。 あとはリストア時にこのダンプファイルをインポートしてやれば RDS for Oracle を DB インスタンス作成じゃなくて今ある DB インスタンスにデータをリストアすることができますね。

 

感想

実は RDS for Oracle から直接 S3 にダンプファイルを送れるとは知りませんでした。 お客様の何気ない一言からこの機能を知りました。 新機能が出たタイミングでは自分ごとではないにしても、いずれ少しでも関係しそうだと思った内容はちゃんと調べてみようと思いました。