HerokuのPostgreSQLでは料金プランごとに使える機能や容量が違います。アプリケーションの使用ユーザーやサイトトラフィックが増えてくると上位のプランに変更する必要が出てきますが、正しい手順に沿って実施しないと思わぬ事故につながる可能性もありますのでまとめてみました。
解説で使用するデータベース構成と料金プランは以下の通りです。
データベース構成
- プライマリー1台
- フォロワー1台
料金プラン
- 変更前:プライマリー、フォロワー共にStandard 0
- 変更後:プライマリー、フォロワー共にStandard 2
プライマリーデータベースの変更手順を中心に解説していきますが、フォロワーデータベースもプライマリーデータベースと同様の手順でアップグレードできます。ただし、フォロワーデータベースはプライマリーデータベースの変更を反映する役割があるため、プライマリーデータベースのアップグレードが完了してから行うことを推奨します。
なお、本番環境への適用前に、必ずステージング環境で十分にテストすることを強く推奨します。
また、Heroku Schedulerなどで設定しているバッチジョブの実行時間がデータベースメンテナンス実行時間と被らないかを確認します。アップグレード中はデータベースへの書き込みを避けるため、バッチジョブの実行時間を調整するなど、事前に対策を講じてください。
データベースメンテナンス作成
まず、postgresの現在の状態を確認します。
heroku pg:info
以下のようにデータベースの情報が表示されます。
# プライマリーデータベース
=== DATABASE_URL
Plan: Standard 0
Status: Available
Data Size: 242 MB / 64 GB (0.37%)
Tables: 103
PG Version: 13.16
Connections: 13/120
Connection Pooling: Available
Credentials: 1
Fork/Follow: Available
Rollback: earliest from 2024-09-16 06:23 UTC
Created: 2020-04-20 02:27
Region: us
Data Encryption: In Use
Continuous Protection: On
Enhanced Certificates: Off
Upgradable Extensions: Yes
Followers: HEROKU_POSTGRESQL_COLOR
Maintenance: not required
Maintenance window: Wednesdays 20:00 to Thursdays 00:00 UTC
Add-on: Add-on name
# フォロワーデータベース
=== HEROKU_POSTGRESQL_COLOR_URL
Plan: Standard 0
Status: Available
Data Size: 242 MB / 64 GB (0.37%)
Tables: 103
PG Version: 13.15
Connections: 10/120
Connection Pooling: Available
Credentials: 1
Fork/Follow: Unavailable on followers
Rollback: earliest from 2024-09-16 06:23 UTC
Created: 2024-04-23 03:12
Region: us
Data Encryption: In Use
Continuous Protection: On (on leader)
Enhanced Certificates: Off
Upgradable Extensions: Yes
Following: DATABASE
Behind By: 0 commits
Maintenance: not required
Maintenance window: Fridays 18:30 to 22:30 UTC
Add-on: Add-on name
以下のコマンドで、プライマリーデータベースのデータベース名とアップグレードするプランを指定し、データベースメンテナンスを作成します。この時点ではまだ実際にアップグレードはされないので、アプリケーションをメンテナンスモードにする必要はなく、ダウンダイムも発生しません。
heroku addons:upgrade DATABASE_URL heroku-postgresql:standard-2
もう一回heroku pg:infoコマンドを実行すると、プライマリーデータベースのStatus項目がUpgrading Planに変更されていることを確認できます。この時点ではPlan項目は古いプランのままです。
heroku pg:info
# プライマリーデータベース
Plan: Standard 0
Status: Upgrading Plan
Data Size: 242 MB / 64 GB (0.37%)
Tables: 103
PG Version: 13.16
Connections: 13/120
Connection Pooling: Available
Credentials: 1
Fork/Follow: Available
Rollback: earliest from 2024-09-16 06:35 UTC
Created: 2020-04-20 02:27
Region: us
Data Encryption: In Use
Continuous Protection: On
Enhanced Certificates: Off
Upgradable Extensions: Yes
Followers: HEROKU_POSTGRESQL_COLOR
Maintenance: not required
Maintenance window: Wednesdays 20:00 to Thursdays 00:00 UTC
Add-on: Add-on name
アップグレードの準備にかかる時間はデータベースの大きさに比例し、数分から数時間の幅があるようですので、時間に余裕を持って事前に実行しておきましょう。
準備ができると、Herokuから以下のようなメールが届いて知らせてくれます。
Maintenance required on your Postgres add-on.
Your database add-on name standard-0 must undergo maintenance. You have requested a plan upgrade on this database.
The maintenance requested will move your database to the new plan.
We’ll notify you when we start the changeover process for the maintenance. We plan on performing this maintenance at 2024-09-25 20:00:00 +0000 during your set maintenance window of Wednesdays 20:00 to Thursdays 00:00 UTC.
You can change the scheduled maintenance window. For example, run the command heroku data:maintenances:window:update DATABASE “Tuesday 14:30” to set a maintenance window for Tuesdays at 2:30pm UTC.
You can also run this maintenance manually at any time with the command heroku data:maintenances:run DATABASE.
Install this plugin before running the data:maintenances commands. See the Heroku Postgres Maintenance article for more details about the maintenance.
また、heroku pg:infoコマンドのStatusとMaintenance表示も以下のように変わります。もし将来ではなく過去のメンテナンス情報が表示されるようであればまだメンテナンス作成中の状態なので、しばらく待つ必要があります。
Plan: Standard 0
Status: Upgrading Plan: Replacing Primary, Maintenance Scheduled
Data Size: 242 MB / 64 GB (0.37%)
Tables: 103
PG Version: 13.16
Connections: 15/120
Connection Pooling: Available
Credentials: 1
Fork/Follow: Available
Rollback: earliest from 2024-09-16 06:46 UTC
Created: 2020-04-20 02:27
Region: us
Data Encryption: In Use
Continuous Protection: On
Enhanced Certificates: Off
Upgradable Extensions: Yes
Followers: HEROKU_POSTGRESQL_COLOR
Maintenance: scheduled for 2024-09-25 20:00:00 +0000, required by 2024-10-04 06:39:40 +0000, replacement currently being prepared
Maintenance window: Wednesdays 20:00 to Thursdays 00:00 UTC
Add-on: postgresql-polished-48934
メンテナンス情報はheroku data:maintenances:infoコマンドでも確認できます。
heroku data:maintenances:info DATABASE_URL
Fetching maintenance… done
addon_attachments: DATABASE_URL
addon_description: Standard Non-HA
addon_kind: heroku-postgresql
addon_name: addon-name
addon_plan: standard-0
addon_window: Wednesdays 20:00 to Thursdays 00:00 UTC
app_name: application-name
method: changeover
reason: routine_maintenance
required_by: 2024-10-04T06:39:40.664+00:00
scheduled_for: 2024-09-25T20:00:00.000+00:00
server_created_at: 2024-08-19T20:51:40.557+00:00
status: preparing
window: Wednesdays 20:00 to Thursdays 00:00 UTC
method項目のchangeoverとは、新しいデータベースに移行することを指しており、status項目がpreparingのうちは、新しいデータベースの作成中ということです。
新しいデータベースの用意ができてデータベースメンテナンスが実行可能になると、status項目がreadyに変わります。
addon_attachments: DATABASE_URL
addon_description: Standard Non-HA
addon_kind: heroku-postgresql
addon_name: addon-name
addon_plan: standard-0
addon_window: Wednesdays 20:00 to Thursdays 00:00 UTC
app_name: app-name
method: changeover
reason: routine_maintenance
required_by: 2024-10-04T06:39:40.664+00:00
scheduled_for: 2024-09-25T20:00:00.000+00:00
server_created_at: 2024-08-19T20:51:40.557+00:00
status: ready
window: Wednesdays 20:00 to Thursdays 00:00 UTC
また、Eメールでも以下のような通知が届きます。
The replacement database is ready for the changeover process on your database addon-name standard-0 (DATABASE on app-name) now. DATABASE_URL on app-name will be updated with the new server address momentarily.
If you’ve copied the value of DATABASE_URL to any other apps or tools, such as database administration tools, you must update those values.
When your database is available again, you can notice temporarily reduced performance while Postgres rebuilds its cache through normal use. For more information on Postgres caching, see Understanding Heroku Postgres Data Caching.
データベースメンテナンス実行
スケジュールされたメンテナンス時間になるまで待ってherokuの自動実行にまかせる手もありますが、ここでは手動で実行する方法を紹介します。
まず、アップグレード中の書き込みを防ぐためにアプリケーションをメンテナンスモードに移行します。
heroku maintenance:on
同様の目的でdyno数も0にしますが、0にする前に現在の数を確認しておきメモしておきます。
heroku ps
webとworkerのdyno数を0にします。
heroku ps:scale web=0 worker=0
DBのバックアップを念の為とっておきます。
heroku pg:backups:capture
データベースのメンテナンスを手動実行します。
heroku data:maintenances:run DATABASE_URL
Triggering maintenance… maintenance triggered
進捗はheroku data:maintenances:infoコマンドで確認します。status項目がrunningのうちは、まだメンテナンスが実行中です。
# コマンド
heroku data:maintenances:info DATABASE_URL
# 出力
addon_attachments: DATABASE_URL
addon_description: Standard Non-HA
addon_kind: heroku-postgresql
addon_name: addon-name
addon_plan: standard-0
addon_window: Wednesdays 20:00 to Thursdays 00:00 UTC
app_name: app-name
method: changeover
reason: routine_maintenance
required_by: 2024-10-04T06:39:40.664+00:00
scheduled_for: 2024-09-20T07:27:09.459+00:00
server_created_at: 2024-08-19T20:51:40.557+00:00
started_at: 2024-09-20T07:27:10.696+00:00
status: running
window: Wednesdays 20:00 to Thursdays 00:00 UTC
メンテナンスが完了するとメールで以下のような通知が届きます。
Maintenance on your database addon-name standard-2 (database-name on app-name) is complete. Your database is ready to use. When your database is available again, you can notice temporarily reduced performance while Postgres rebuilds its cache through normal use. For more information on Postgres caching, see Understanding Heroku Postgres Data Caching.
また、heroku data:maintenances:infoの出力も表示が変わり、新しいプラン、メンテナンス終了時間、実行にかかった時間、ステータスなどが表示されます。
addon_attachments: DATABASE_URL
addon_description: Standard Non-HA
addon_kind: heroku-postgresql
addon_name: addon-name
addon_plan: standard-2
addon_window: Wednesdays 20:00 to Thursdays 00:00 UTC
app_name: app-name
completed_at: 2024-09-20T07:28:20.905+00:00
duration_approximate: ~ 1 minute
duration_seconds: 70
method: changeover
reason: routine_maintenance
required_by: 2024-10-04T06:39:40.664+00:00
scheduled_for: 2024-09-20T07:27:09.459+00:00
server_created_at: 2024-08-19T20:51:40.557+00:00
started_at: 2024-09-20T07:27:10.696+00:00
status: completed
window: Wednesdays 20:00 to Thursdays 00:00 UTC
メンテナンス実行が終わり新しいデータベースに移行されると、フォロワーデータベースは自動的に新しいプライマリーデータベースをフォローするように再起動されます。
なお、プライマリーデータベースのプランをアップグレードしたとしても、フォロワーデータベースのプランが自動的に変わるわけではありません。heroku pg:infoコマンドで、プライマリーはStandard 2プランに変更されていますが、フォロワーはStandard 0のままであることを確認できます。
heroku pg:info
# プライマリー
=== DATABASE_URL
Plan: Standard 2
Status: Available
Data Size: 242 MB / 256 GB (0.09%)
Tables: 103
PG Version: 13.16
Connections: 13/400
Connection Pooling: Available
Credentials: 1
Fork/Follow: Temporarily Unavailable
Rollback: earliest from 2024-09-20 07:31
Created: 2020-04-20 02:27
Region: us
Data Encryption: In Use
Continuous Protection: On
Enhanced Certificates: Off
Upgradable Extensions: Yes
Followers: HEROKU_POSTGRESQL_COLOR
Maintenance: not required
Maintenance window: Wednesdays 20:00 to Thursdays 00:00 UTC
Add-on: addon-name
# フォロワー
=== HEROKU_POSTGRESQL_COLOR_URL
Plan: Standard 0
Status: Available
Data Size: 242 MB / 64 GB (0.37%)
Tables: 103
PG Version: 13.15
Connections: 10/120
Connection Pooling: Available
Credentials: 1
Fork/Follow: Unavailable on followers
Rollback: earliest from 2024-09-20 07:31
Created: 2024-04-23 03:12
Region: us
Data Encryption: In Use
Continuous Protection: On (on leader)
Enhanced Certificates: Off
Upgradable Extensions: Yes
Following: DATABASE
Behind By: 0 commits
Maintenance: not required
Maintenance window: Fridays 18:30 to 22:30 UTC
Add-on: addon-name
フォロワーがプライマリーより低位のプランでも容量が足りればすぐに問題になることはありませんが、万が一フォロワーをプライマリーに切り替えなければならないときにdyno数に対してコネクション数が足りないなどの問題が発生するリスクがありますので、フォロワーも同じ手順でプライマリーと同じプランに変更しておくことをおすすめします。
データベースメンテナンスが終わったら、dyno数を元に戻します。
heroku ps:scale web=1 worker=1
もしHeroku schedulerなどでのバッチジョブ実行時間を一時的に変更していたら、元の時間に戻します。
アプリケーションのメンテナンスを終了します。
heroku maintenance:off
アプリケーションで動作確認をし、正常に動いていればアップグレード完了です。
まとめ
HerokuでのPostgreSQLプラン変更には新規データベースへの移行が伴いますので、事前にしっかりと手順を確認しておきましょう。そうすることで、アプリケーションのダウンタイムを最小限に抑えられるはずです。
