🐘

AWS Aurora for PostgreSQL から pg_dumpall のバックアップをS3に直接転送

2023/03/07に公開

長いタイトルになってしまった。

AWS Auroraは標準でバックアップ機能を持っているので、コンソールで設定しておけばバックアップをとってくれる。
ただ、本当に事業の根幹に関わるようなデータを長年にわたって蓄積しているような場合、私自身はそれだけでは不安なので、Auroraに限らずPostgreSQLにリストアできるような標準のバックアップもとっておきたいと思い、最終的に以下の方法に落ち着いたので書いておきます。

条件

  • バックアップの実行はEC2(OS: Ubuntu)で行いましたが、Linuxであれば同等の方法で大丈夫と思います。
  • PostgreSQL標準の pg_dumpall を使用して全データベースを丸ごとバックアップ。
  • 本番環境に極力影響を与えないように、エンドポイントは読み取り専用エンドポイントを使う。
    • グローバルデータベースで複数リージョンに展開しているなら、バックアップリージョンで実行するのが望ましい。
  • バックアップ先はS3バケットとする。ローカルに一時ファイルを作らず、標準入力/出力を使って pg_dumpall の出力をそのまま gzip に渡して圧縮し、さらに圧縮結果を aws コマンドに渡しS3へ転送する。
    • ローカルに一時ファイルを作らなければEBSのサイズを小さく抑えられるのでコストダウンになる。

準備

必要なものをインストールしておく。

PostgreSQLクライアントをインストール(バージョンは使用しているAuroraのPostgreSQLバージョンに合わせる)

$ sudo apt install postgresql-client-12

aws cliをインストール(Installing or updating the latest version of the AWS CLI より)

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install

スクリプト

  • 実行スクリプトを書く。認証ユーザー名、認証パスワード、読取エンドポイント、S3バケット名は自分の環境の値で置き換える。
  • 必要に応じて実行するEC2インスタンスにS3へのアクセス権をもったIAMロールを付与する。
  • 以下のスクリプトではS3に保存されるときのファイル名に日付を付与している。
  • また、 --exclude-database=rdsadmin のようにバックアップする権限が無いテーブルは除外する。

ポイントとして、

/usr/bin/pg_dumpall --no-role-passwords --exclude-database=rdsadmin | gzip -c | /usr/bin/aws s3 cp - s3://[バックアップ先バケット名]/aurora/${filename}

というところで、awsコマンドでは標準入力/標準出力を - で表現することを利用しています。

/usr/local/bin/aurora_backup
#!/bin/bash

export LANG=C
export PGCLIENTENCODING=UTF8
export PGUSER=[ 認証ユーザー名 ]
export PGPASSWORD=[ 認証パスワード ]
export PGHOST=[Aurora for PostgreSQL 読取エンドポイント]

starttime=`date`

filename=db-`date '+%Y%m%d%H%M%S'.gz`
echo "${starttime}: creating backup ${filename} ..."
/usr/bin/pg_dumpall --no-role-passwords --exclude-database=rdsadmin | gzip -c | /usr/bin/aws s3 cp - s3://[バックアップ先バケット名]/aurora/${filename}

endtime=`date`
echo "${endtime}: done."

実行権限を与える

$ sudo chmod 755 /usr/local/bin/aurora_backup

ここで一旦実行してみて、問題なくS3バケットにバックアップが取れることを確認。
合わせてローカルに一時ファイルが作られていないことも確認。

Cronで定時実行

Auroraのバックアップで逐一とっているので、こちらは週に一回とるものとする。

/etc/cron.d/backup
0 7 * * 0 ubuntu /usr/local/bin/aurora_backup

今回は毎週日曜日の朝7時に実施するものとした。
曜日の指定は以下の通り

0 sun
1 mon
2 tue
3 wed
4 thu
5 fri
6 sat

S3のコストを抑えるためにライフサイクルを設定する

やりたいこと概要

サイズが小さければ気にする必要はないけど、データベースのバックアップはサイズが大きくなりがちなので、コストダウンのためにS3のライフサイクルを設定しておく。

やりたいことは

  • バックアップデータがS3にアップロードされてから
    • 1ヶ月後に「標準 - IA」 に移動する。
    • 3ヶ月後に「Glacier Flexible Retrieval (旧 Glacier) 」に移動する。
    • 6ヶ月後に「Glacier Deep Archive 」に移動する。
    • 1年後に有効期限切れになる。
    • 1年と7日後に完全に削除。

のような流れになります。

手順

  • AWSコンソール -> S3 -> 保存先バケット -> 「管理」タブ -> 「ライフサイクルを作成する」 をクリック

以下のように設定した。




動作確認

実際に運用して、バックアップがS3に保存されることと、S3のライフサイクルが意図した通りになっていることを確認しておわり!

Discussion