Herokuからmysqldumpを定期的にS3にバックアップする方法
こんにちは、たつきちです。
Heroku でMySQLを使う場合、Heroku Add-onである JawsDB MySQL や ClearDB MySQL を使うのが一般的かと思います。
PostgreSQLなら、公式の Heroku Postgres というAdd-onにバックアップ機能が組み込まれているのですが、JawsDBやClearDBを使う場合は特にそういう機能はないので手動でmysqldumpする必要があります。
JawsDBもClearDBも、Herokuのdyno以外のホストからでも普通に接続できるので、適当なVPSなどでmysqldumpを定期実行するような運用でもいいのですが、せっかくなのでdyno自身からmysqldumpしてバックアップはS3に保存するような形にできるときれいですよね。
というわけで、毎日0:00に自動でdyno上でmysqldumpを実行して、バックアップファイルをS3に保存するように設定してみましたので、この記事ではその方法をご紹介します。(ググってみても同じことをやってる人が見当たらなかったので意外と地味にお役立ち情報かもしれません)
なお、S3を使うので微々たるものとは言え費用が発生し得ます。あらかじめご留意ください。
使うもの
これだけ見ればやろうとしていることの流れはだいたい分かるかもしれません。
ざっくり言うと、
- dynoにmysqlクライアントを入れる
- dynoにawscliを入れる
- Heroku Schedulerをインストールする
- Heroku Schedulerで毎日mysqldumpをS3に保存するように設定する
ということをします。
具体的な手順
では、手順をもう少し具体的に説明します。
1. dynoにmysqlクライアントを入れる
heroku buildpack mysql
とかをググると結構たくさん出てくるんですが、いずれもすでにメンテナンスされておらず、2020/01現在のHerokuの stack では使えなくなっています。
自分でバイナリを用意してbuildpackを作ろうかなとも思ったのですが、よくよく調べてみると heroku-buildpack-apt というbuildpackを使えばdyno起動時に任意のパッケージを apt install
できるということが分かりました。
ということで、これを使ってdynoにmysqlクライアントをインストールします。
使い方は簡単で、
- buildpackに
heroku-community/apt
を追加 - コードベースのプロジェクトルートに
Aptfile
というファイルを追加し、apt install
したいパッケージ名を書く
これだけです。
今回は Aptfile
には
mysql-client
とだけ書いておけばOKです。
2. dynoにawscliを入れる
dyno上でmysqldumpができるようになったら、次はそれをS3にアップロードできるようにする必要があります。
ここでもありがたいことに buildpackが用意されている ので、これを使います。
使い方は、
- buildpackに
heroku-community/awscli
を追加 - dynoの環境変数に
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION
の3つを設定
です。
環境変数に設定するアクセスキーやシークレットは、アップロード先のS3バケットに対して書き込み権限のあるIAMユーザーのものをセットしてください。
S3やIAM自体のセットアップ方法については、今回は割愛します。
3. Heroku Schedulerをインストールする
ここまでで、dyno上からmysqldumpコマンドとawsコマンドを使える状態になったので、あとはバックアップ操作をスケジュール化するために Heroku Scheduler をHerokuアプリにインストールしましょう。
4. Heroku Schedulerで毎日mysqldumpをS3に保存するように設定する
Heroku Schedulerがインストールできたら、 https://dashboard.heroku.com/apps/<アプリ名>/scheduler
からHeroku Schedulerの管理画面へ行き、 Add Job
ボタンでジョブを登録します。
実行するコマンドは以下のようなものでよいでしょう。
mysqldump -u{ユーザー名} -p{パスワード} -h{ホスト名} {データベース名} > mysqldump.sql && tar zcvf mysqldump.tar.gz mysqldump.sql && aws s3 cp mysqldump.tar.gz s3://{バケット名}/mysqldump.tar.gz
バケット内のパスなど適宜変更してください。
スケジュールは、毎日0:00 JSTに実行するなら以下のような感じです。
今回はとりあえず毎日同じファイル名で上書き保存するようにしましたが、ワンライナーを工夫すれば直近1週間分がローテーションで保存されるような感じにもできると思います。
まとめ
- Heroku Scheduler、heroku-buildpack-apt、heroku-buildpack-awscliを使えば、dyno上でmysqldumpをS3にアップロードさせる処理を定期実行できる
- なぜPostgreSQLは公式Add-onがあるのにMySQLはないのか
Discussion