💻

Herokuからmysqldumpを定期的にS3にバックアップする方法

2020/01/30に公開

こんにちは、たつきちです。

Heroku でMySQLを使う場合、Heroku Add-onである JawsDB MySQLClearDB MySQL を使うのが一般的かと思います。

PostgreSQLなら、公式の Heroku Postgres というAdd-onにバックアップ機能が組み込まれているのですが、JawsDBやClearDBを使う場合は特にそういう機能はないので手動でmysqldumpする必要があります。

JawsDBもClearDBも、Herokuのdyno以外のホストからでも普通に接続できるので、適当なVPSなどでmysqldumpを定期実行するような運用でもいいのですが、せっかくなのでdyno自身からmysqldumpしてバックアップはS3に保存するような形にできるときれいですよね。

というわけで、毎日0:00に自動でdyno上でmysqldumpを実行して、バックアップファイルをS3に保存するように設定してみましたので、この記事ではその方法をご紹介します。(ググってみても同じことをやってる人が見当たらなかったので意外と地味にお役立ち情報かもしれません)

なお、S3を使うので微々たるものとは言え費用が発生し得ます。あらかじめご留意ください。

使うもの

これだけ見ればやろうとしていることの流れはだいたい分かるかもしれません。

ざっくり言うと、

  1. dynoにmysqlクライアントを入れる
  2. dynoにawscliを入れる
  3. Heroku Schedulerをインストールする
  4. Heroku Schedulerで毎日mysqldumpをS3に保存するように設定する

ということをします。

具体的な手順

では、手順をもう少し具体的に説明します。

1. dynoにmysqlクライアントを入れる

heroku buildpack mysql とかをググると結構たくさん出てくるんですが、いずれもすでにメンテナンスされておらず、2020/01現在のHerokuの stack では使えなくなっています。

自分でバイナリを用意してbuildpackを作ろうかなとも思ったのですが、よくよく調べてみると heroku-buildpack-apt というbuildpackを使えばdyno起動時に任意のパッケージを apt install できるということが分かりました。

ということで、これを使ってdynoにmysqlクライアントをインストールします。

使い方は簡単で、

  1. buildpackに heroku-community/apt を追加
  2. コードベースのプロジェクトルートに Aptfile というファイルを追加し、 apt install したいパッケージ名を書く

これだけです。

今回は Aptfile には

mysql-client

とだけ書いておけばOKです。

2. dynoにawscliを入れる

dyno上でmysqldumpができるようになったら、次はそれをS3にアップロードできるようにする必要があります。

ここでもありがたいことに buildpackが用意されている ので、これを使います。

使い方は、

  1. buildpackに heroku-community/awscli を追加
  2. 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はないのか
GitHubで編集を提案

Discussion