猫でもわかるWebプログラミング

試行錯誤しながらエンジニア(プログラマー)として働く猫のブログ。技術的な話や、働き方の話、読書録とか、試行錯誤している日常の話。

Heroku PostgreSQL を、hobby-dev (無料) -> hobby-basic (9ドル/月) にする

f:id:yoshiki_utakata:20200408170047p:plain

はじめに

先日、このようなメールがHerokuから届きました。

The database DATABASE_URL on Heroku app lgtmoon has exceeded its allocated storage capacity. Immediate action is required.

The database contains 10,696 rows, exceeding the Hobby-dev plan limit of 10,000. INSERT privileges to the database will be automatically revoked in 7 days. This will cause service failures in most applications dependent on this database.

To avoid a disruption to your service, migrate the database to a Hobby Basic ($9/month) or higher database plan:

Heroku PostgreSQL の無料プラン(hobby-dev)の制限である 10,000 レコードを超えているので、7日後に inesert ができないようにするよ。というメールです。

Heroku PostgreSQL の hobby-dev プランは無料で利用できるのですが、10,000レコードが上限になっています。普通にアプリを作るとすぐ10,000レコードまで達してしまいます。この hobby-dev の一つ上のプランが hobby-basic で、これは10,000,000レコードまでのデータを持てるようになります。

LGTMoon(https://lgtmoon.herokuapp.com/)はかなりレコードを節約する形で実装したのですが、3年ほど運用して10,000レコードを超えてしまったので、 hobby-basic にアップグレードしようと思います。

アップグレードの方法について

hobby 系のプランの場合、課金しても勝手にDBの容量が上がるわけではないので注意が必要です。別DBが新しく作成されるので、データを移動したりする必要があります。

  1. 新しくhobby-basicのDBをアプリに追加
  2. 旧hobby-devのデータを新しいhobby-basicの方コピー
  3. アプリケーションの向き先DBを変更

新しくhobby-basicのPostgreSQLを追加

heroku cli を利用しているとコマンド一発でできます。

$ heroku addons:create heroku-postgresql:hobby-basic

Creating heroku-postgresql:hobby-basic on ⬢ lgtmoon... $9/month
Database has been created and is available
 ! This database is empty. If upgrading, you can transfer
 ! data from another database with pg:copy
Created postgresql-flat-xxxxx as HEROKU_POSTGRESQL_GOLD_URL
Use heroku addons:docs heroku-postgresql to view documentation

postgresql-flat-xxxxx という名前のDBができました。

f:id:yoshiki_utakata:20190226100453p:plain

このように、もともとあった hobby-dev に加えて新しく hobby-basic ができます。コマンド一発で簡単にできますが、 $9.00/month と書いてあるように、課金が始まるので注意してください。*1

コマンドでなくとも Configure Add-ons のボタンを押せばUI上から追加できます。

必要であればアプリをメンテナンスに入れる

データ移行のとき、必要であればアプリケーションをメンテナンスに入れることができます。

Heroku CLI から

heroku maintenance:on

またはWebのUIから

  • アプリケーション名 > Settings > 下の方にスクロールして「Maintenance Mode」

からメンテナンスに入れることができます。LGTMoonはメンテナンスに入れなくても(移行中に生成された画像は消えたりするかもしれないけど)あんまり影響ないかなーと思ってメンテナンスには入れませんでした。

データをコピーする

heroku addons でアドオン一覧が見られます。

$ heroku addons

heroku-postgresql (postgresql-xxxx-xxxxx)        hobby-basic  $9/month  created
 └─ as HEROKU_POSTGRESQL_GOLD

heroku-postgresql (postgresql-xxxx-xxxxx)  hobby-dev    free      created
 └─ as DATABASE

DATABASE がいままでのやつ、HEROKU_POSTGRESQL_GOLD が新しいやつです。

pg:copy コマンドでデータをコピーします。

$ heroku pg:copy <旧データベースのURL> HEROKU_POSTGRESQL_GOLD --app lgtmoon

▸    WARNING: Destructive action
 ▸    This command will remove all data from GOLD
 ▸    Data from DATABASE will then be transferred to GOLD
 ▸    To proceed, type lgtmoon or re-run this command with --confirm lgtmoon

注意点としては

  • 旧データベースのURLはHerokuのWeb UIのSettingsか、 heroku pg:info コマンドで調べられます。
  • 旧データベースのURLはちゃんとしたURLを正確に入れる必要があります。
  • HEROKU_POSTGRESQL_GOLDheroku addons で確認した as XXXXX の部分の名前です。

これを実行すると

  • GOLD(新しいDB)の方のデータは全部消えるよ
  • 旧DB からGOLD(新しいDB)にデータがコピーされるよ
  • よろしければ lgtmoon (アプリの名前)と入力してね

と出てくるので lgtmoon と入れます。

> lgtmoon
Starting copy of database dlm8a3q4ffa4b on ec2-54-197-253-210.compute-1.amazonaws.com:5432 to GOLD... done
Copying... done

1.7GBのデータでしたが、1分ほどでコピー完了。Webの画面でコピーされたことを確認します。

f:id:yoshiki_utakata:20190226103856p:plain

アプリケーションの接続先をDB変更する

環境変数の接続先を見ている場合以下のコマンドで差し替わります。

heroku pg:promote HEROKU_POSTGRESQL_GOLD

僕はconfigに設定をべた書きしているので、アプリを変更してデプロイする必要がありました。

古いDBを消す

しばらく運用してみます。データ数の増減を確認したり、connections を見て、新しいDBの方に切り替わっていたら問題ないでしょう。

不要になった古いDBを消してしまいます。Heroku CLIから実行する場合は以下のコマンドです。

heroku addons:destroy 古いDB

その他注意点

新しく追加されたPostgreSQLのDBはバージョンが上がっていたりするので、動作検証は事前にしておいたほうがいいかも。

参考

*1:Herokuのアカウント作成時に登録したクレジットカードに請求されます。