Herokuでデータベースのバックアップを行いたい

# はじめに
Heroku Postgresを使っていれば、他のアドオンを追加することなしにバックアップを利用することができます。この記事ではHeroku Postgresのデータベースのバックアップの取得方法、リストア方法、運用方法をまとめていきたいと思います。

# やりたいこと
* データベースのバックアップを取りたい
 * 手動バックアップを取りたい
 * 定期バックアップを取りたい
* リストアをしたい
* ステージング環境に本番データを投入したい
* バックアップデータをローカル環境に落としておきたい

# データベースのバックアップを取りたい
## 手動バックアップを取りたい
#### Webの管理画面からバックアップを行う
[Heroku Postgresの管理画面](https://postgres.heroku.com/databases)からバックアップを取得できます。"PG Backups"の画面でバックアップやリストアの操作ができます。わりと直感的に操作ができると思いますので、操作方法の説明は省かせていただきます。

### Herokuコマンドからバックアップを行う
[Creating a backup](https://devcenter.heroku.com/articles/heroku-postgres-backups#creating-a-backup)

`heroku pg:backups`コマンドでバックアップ操作を行えます。手動バックアップは`capture`サブコマンドで取得できます。以下のコマンドで`--app`で指定したアプリケーションで使っているデータベースのバックアップを取ります。
`$ heroku pg:backups capture --app your-app-name`

実行例

```shell-session
$ heroku pg:backups capture --app some-application

Use Ctrl-C at any time to stop monitoring progress; the backup
will continue running. Use heroku pg:backups info to check progress.
Stop a running backup with heroku pg:backups cancel.

DATABASE ---backup---> b007

Backup completed

$ # 一覧表示: b007というバックアップができていることがわかる
$ heroku pg:backups --app some-application 
=== Backups
ID    Backup Time                Status                              Size    Database
----  -------------------------  ----------------------------------  ------  --------
b007  2015-07-31 14:38:43 +0000  Finished 2015-07-31 14:38:46 +0000  14.9kB  DATABASE
b006  2015-07-31 14:11:45 +0000  Finished 2015-07-31 14:11:46 +0000  14.9kB  DATABASE

=== Restores
No restores found. Use `heroku pg:backups restore` to restore a backup

=== Copies
No copies found. Use `heroku pg:copy` to copy a database to another

```

## 定期バックアップを取りたい
[Scheduling backups
](https://devcenter.heroku.com/articles/heroku-postgres-backups#scheduling-backups)

定期バックアップを取るには、`schedule`サブコマンドを使います。
例として、AM 2:00にバックアップを取得する設定をします。時刻の後ろにはタイムゾーンを指定します。ここではAsia/Tokyoとしています。
`$ heroku pg:backups schedule DATABASE_URL --at '02:00 Asia/Tokyo' --app your-app-name`

実行例

```shell-session
$ heroku pg:backups schedule DATABASE_URL --at '02:00 Asia/Tokyo' --app some-application
Scheduled automatic daily backups at 02:00 Asia/Tokyo for DATABASE
```

設定した定期バックアップのスケジュール確認は`schedules`サブコマンドを使います。
`$ heroku pg:backups schedules --app your-app-name`

定期バックアップを削除するには`unschedule`サブコマンドを使います。
`$ heroku pg:backups unschedule DATABASE_URL --app your-app-name`

# リストアをしたい
[Restoring backups](https://devcenter.heroku.com/articles/heroku-postgres-backups#restoring-backups)

リストアをするには`restore`サブコマンドを使います。`b100`には対象のバックアップIDを入力します。
`$ heroku pg:backups restore b100 DATABASE_URL --app your-app-name 
`

このままコマンドを打つと以下の警告が出ます。投入先のアプリケーション名が正しいことを確認後、アプリケーション名を入力するとリストアが始まります。

```shell-session
 !    WARNING: Destructive Action
 !    This command will affect the app: your-app-name
 !    To proceed, type "your-app-name" or re-run this command with --confirm your-app-name
```

# ステージング環境に本番データを投入したい
ステージング環境の作り方は次の記事を参考にしてください。
[Herokuでステージング環境を作成する](http://qiita.com/kimunny/items/fea2b3d3fb350cce7d4b)

上記の方法でステージング環境を作ればその時点での本番データをステージング環境に投入されていますが、環境の作成から時間が経過した場合など、再度同期したいタイミングが出てくると思います。リストア時にステージング環境のアプリケーションを指定すれば、本番データの投入が可能になります。

`your-app-name`には本番のアプリケーション名、`b101`には本番データのバックアップID、`your-app-name-st`にはステージングのアプリケーション名を指定します。

`$ heroku pg:backups restore your-app-name::b101 DATABASE_URL --app your-app-name-st --confirm your-app-name-st`

--confirmオプションをつけると確認ダイアログをパスできます。

# バックアップデータをローカル環境に落としておきたい
[Downloading your backups](https://devcenter.heroku.com/articles/heroku-postgres-backups#downloading-your-backups)

[Heroku Postgresの管理画面](https://postgres.heroku.com/databases)からもバックアップデータをダウンロードすることができますが、コマンドラインでももちろん可能です。
バックアップデータはAWSのS3上に置かれているのですが、`heroku pg:backups public-url`コマンドで公開URLを取得し、curlなどでダウンロードをします。

``$ curl -o latest.dump `heroku pg:backups public-url -a your-app-name` ``

なお、このデータはPostgreSQLのダンプデータですので、ローカル環境にインストールしたPostgreSQL上に復元することもできます。

# 【補足】バックアップの世代について
契約しているデータベースプランによってバックアップを保持できる世代数や保持期間が変わるので注意が必要です。例えば、手動バックアップの保持できる世代数は無料のHobby-Devであれば2世代、有料のStandardであれば25世代となっています。また、定期バックアップの保持期間は無料のHobby-Devであれば1週間、有料のStandardであれば4週間となっています。

詳細は以下の資料を確認してください。

* [手動バックアップの保持制限について](https://devcenter.heroku.com/articles/heroku-postgres-backups#manual-backup-retention-limits)
* [定期バックアップの保持制限について](https://devcenter.heroku.com/articles/heroku-postgres-backups#scheduled-backups-retention-limits)

# 参考資料
この記事を書くために以下の公式資料を参考にしました。
[Heroku PGBackups](https://devcenter.heroku.com/articles/heroku-postgres-backups)

以上です。