プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

PostgreSQLのバックアップを設定

heroku には無料で使える便利なアドオンがたくさんあるそうです。この無料で使えるアドオンに、PostgreSQLのバックアップを取るというものがありました。せっかく無料で使えるのだからと早速使ってみます。

 

アドオンについて

herokuでは、無料のアドオンを使う場合でも、アカウントの認証(要はクレジットカードの登録)が必要になります。ただし、heroku-postgresql:dev と pgbackups:plus は例外的にアカウントの認証がなくても使えるそうです(詳しくは、Account Verification を参照)。

 

とはいえ、他にも使いたい無料アドオンがあったので、間違った使い方をすると課金されるかもと思うと、ドキドキですが、仕方ないのであきらめて登録しておきます。

 

PG Backupsについて

こちらのPG Backups紹介のページにあるように、基本無料で使えます。プランには3種類あって、残せるバックアップの種類と数で分けられているようです。

 

Plusはマニュアルバックアップのみ、Auto-One Month Retention はdailyでバックアップを取り、一ヶ月分まで残してくれるようです(マニュアルバックアップも2つまでOK)。Auto-one Week Retention は一週間分ですね。

他にも、今回は試しませんでしたが、バックアップしたデータをheroku外にエクスポートしたり、逆にインポートしたりといったことも無料の範囲で出来るようです。

詳しくはPG Backupsのドキュメントをご覧ください。

 

アドオンの有効化

とりあえず、最初はPlusを試してみます。以下で出てくるbuslockというのがアプリケーションの名前です。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku addons:add pgbackups
Adding pgbackups on buslock... done, v18 (free)
You can now use "pgbackups" to backup your databases or import an external backup.
Use `heroku addons:docs pgbackups` to view documentation.
mor@T105-PandRDev:~/work/projects/pandr/vehicle$ 

 pgbackupsとだけ指定した場合は、Plusになります。

 

バックアップ操作

まず、保持しているバックアップを見てみます。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pgbackups
 !    No backups. Capture one with `heroku pgbackups:capture`.

当然なにもバックアップはありません。

 

次に、マニュアルでバックアップを取ってみます。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pgbackups:capture

HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL)  ----backup--->  b001

Capturing... done
Storing... done

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ 

確認すると

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pgbackups
ID    Backup Time          Status                          Size    Database
----  -------------------  ------------------------------  ------  ---------------------------------------------
b001  2013/10/08 01:29.18  Finished @ 2013/10/08 01:29.29  25.5KB  HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL)
mor@T105-PandRDev:~/work/projects/pandr/vehicle$ 

となり、バックアップが取れているのが分かります。

 

なお、バックアップデータそのものは、S3にあるようです(こちらのダウンロード用URLの画面をみるとS3を指しています)。

 

バックアップの削除

ま、テストで取ったバックアップなので消してしまいましょう。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pgbackups:destroy b001
Destroying b001... done
mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pgbackups
 !    No backups. Capture one with `heroku pgbackups:capture`.
mor@T105-PandRDev:~/work/projects/pandr/vehicle$ 

きちんと消えていることが分かります。

 

バックアップからのリストア

では、リストアを試してみましょう。まず、バックアップを取ります。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pgbackups:capture

HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL)  ----backup--->  b002

Capturing... done
Storing... done

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pgbackups
ID    Backup Time          Status                          Size    Database
----  -------------------  ------------------------------  ------  ---------------------------------------------
b002  2013/10/08 01:31.32  Finished @ 2013/10/08 01:31.39  25.5KB  HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL)
mor@T105-PandRDev:~/work/projects/pandr/vehicle$ 

いまのデータベースの状態を確認しておきます。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pg:info
=== HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL)
Plan:        Dev
Status:      available
Connections: 1
PG Version:  9.2.4
Created:     2013-07-17 10:49 UTC
Data Size:   7.2 MB
Tables:      9
Rows:        172/10000 (In compliance)
Fork/Follow: Unsupported

テーブルが9個、レコードが172あることが分かります。

 

バックアップ後にテーブルが作られたりしてると、ややこしくなるので、リストア前に一度全データを消しておきます。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pg:reset DATABASE

 !    WARNING: Destructive Action
 !    This command will affect the app: buslock
 !    To proceed, type "buslock" or re-run this command with --confirm buslock

> buslock
Resetting HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL)... done

データベースのリセットを行うと、データの復元が出来なくなるので、間違って消さないようにアプリケーション名の入力が求められます。

 

きちんと消えたことを確認しておきます。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pg:info
=== HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL)
Plan:        Dev
Status:      available
Connections: 1
PG Version:  9.2.4
Created:     2013-07-17 10:49 UTC
Data Size:   6.7 MB
Tables:      0
Rows:        0/10000 (In compliance)
Fork/Follow: Unsupported

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ 

テーブルごと消えているのが分かります(テーブル数が0個になってます)。

 

では、リストアしてみましょう。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pgbackups:restore

HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL)   buslock

Retrieving... done
Restoring... done

mor@T105-PandRDev:~/work/projects/pandr/vehicle$

問題なくリストアできたようです。

 

確認のため、もう一度データベースの状態を見てみます。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku pg:info
=== HEROKU_POSTGRESQL_CHARCOAL_URL (DATABASE_URL)
Plan:        Dev
Status:      available
Connections: 1
PG Version:  9.2.4
Created:     2013-07-17 10:49 UTC
Data Size:   7.4 MB
Tables:      9
Rows:        239/10000 (In compliance)
Fork/Follow: Unsupported

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ 

きちんと戻りましたね。。。と言いたかったのですが、えっと、テーブルの個数はリストア前と同じになっているのですが、レコード数が微妙に異なっています。なんだこれは?

ただ、実際にデータを見た感じでは、データの重複があったり、訳分からないデータが追加されているとかいう感じは無かったです(もちろん全レコードを確認してはいませんが)。また、pgAdminで各テーブルのデータ数を合計しても、239と一致していました。

一応、このままでは気持ち悪いので、何回かテストしてみたのですが、同じような現象は再現できず、結局のところ原因が良く分かりませんでした。

ちょっと強引かもしれませんが、pg:infoコマンドのRowsの表示が必ずしも最新の情報を表しておらず、リストア前のレコード数(172件)が古い情報だったのではないかと推測しています(リストア前のレコード数をpgAdmin等でも確認しておくべきでした、失敗したな)。

もうしばらく、これについてはバックアップのテストを行いながら様子を見ようと思います。

 

プランの変更

ちょっと挙動が理解し切れていないところもありますが、マニュアルでのバックアップ操作が問題なくできたので、プランをAuto-One Month Retention に変更しようと思います。

mor@T105-PandRDev:~/work/projects/pandr/vehicle$ heroku addons:upgrade pgbackups:auto-month
Upgrading to pgbackups:auto-month on buslock... done, v19 (free)
Plan upgraded
Use `heroku addons:docs pgbackups:auto-month` to view documentation.
mor@T105-PandRDev:~/work/projects/pandr/vehicle$ 

これで一か月分、毎日バックアップを取ってくれるようになりました。

 

(参考)

特盛!Heroku (p.30あたりにPG Backups のことが出てきます。)