Table of Contents [expand]
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2025年06月17日(火)
この記事では、Heroku Postgres データベースのメジャー Postgres バージョンをアップグレードする方法について説明します。Heroku でサポートされている最新のメジャー Postgres バージョンは 17 です。
ユーザーは、データベースのマイナーバージョンを自分で更新することはできません。新しいマイナーバージョンが利用可能で、データベースが最新のマイナーバージョンでない場合は、Standard 層およびそれ以上のプランの各データベースメンテナンスの後に Heroku によってマイナーバージョンが自動的に更新されます。
メジャー Postgres バージョンは Heroku CLI 経由でのみアップグレードできます。これは、慎重に実行する必要のある重大な操作です。
Heroku では、データベースの Postgres バージョンをアップグレードするための 3 つの方法がサポートされています。どの方法でも、アップグレード中のデータ損失を防ぐために、ある程度のアプリケーションのダウンタイムが必要になります。
| アップグレード方法 | 説明 |
|---|---|
pg:upgrade:* コマンド (推奨) |
すべての Heroku Postgres プランで機能し、推奨されている方法です。 多くの場合、約 5 ~ 10 分のダウンタイムが必要ですが、この量は変動する場合があります。 |
| フォロワーデータベース | Essential 層プランを除くすべての Heroku Postgres プランで動作します。 多くの場合、約 30 分のダウンタイムが必要ですが、この量は変動する場合があります。 |
pg:copy |
10 GB 未満の Essential、Standard、Premium、Private 層の Heroku Postgres プランでのみ機能します。
PGBackups は Shield データベースで機能しないため、Shield 層のプランではサポートされていません。 多くの場合、GB あたり約 3 分のダウンタイムが必要ですが、この量は大きく変動する場合があります。 |
データベースをバージョン 15、16、17 にアップグレードできます。--version フラグを使用して、アップグレードするバージョンを指定します。たとえば、Postgres 16 にアップグレードする場合は、--version 16 を追加します。--version フラグを設定しなかった場合は、デフォルトで最新バージョンにアップグレードされます。
アップグレード処理は、大量のスキーマがあるデータベースではメモリ不足エラーのため失敗する可能性があります。データベースに 1,000 以上のスキーマがあるか、10,000 以上のオブジェクトが格納されている場合は、アップグレードを事前にテストし、アップグレードが失敗する場合はサポートチケットを開いてください。
pg:upgrade:* コマンドでのアップグレード
pg:upgrade:* コマンドを使用してEssential 層のデータベース、Standard 層以上のデータベース、およびフォロワーデータベースのバージョンアップグレードを実行することができます。
これらのコマンドを使用するには、Heroku CLI v10.8.0 以降を使用する必要があります。CLI バージョンを更新するには、heroku update を使用します。
アップグレードコマンドは、PostgreSQL の pg_upgrade ユーティリティを使用して PostgreSQL バージョンをその場でアップグレードします。これらのコマンドを使用してバージョンのアップグレードを実行するには、多くの場合、約 5 ~ 10 分のアプリのダウンタイムが必要になります。
Essential 層およびフォロワー
Postgres バージョンのアップグレード用の pg:upgrade CLI コマンドが変更されます。サポートが終了するまでは引き続き pg:upgrade も使用できますが、新しいアップグレードコマンドを使用して Postgres バージョンをアップグレードすることをお勧めします。詳細は、こちらのヘルプ記事を参照してください。
この方法は全 Essential 層の Heroku Postgres プランおよびフォロワーデータベースでサポートされています。フォロワーデータベースでこの方法を使用すると、フォロワーの Postgres バージョンをアップグレードする前に、リーダーデータベースのフォローが解除されます。
バージョンをアップグレードするには、次のデータベースで直接 pg:upgrade:run を実行します。
$ heroku pg:upgrade:run HEROKU_POSTGRESQL_RED --app example-app
Standard 層およびそれ以上
アップグレードコマンドを使用してデータベースバージョンをアップグレードするには、次の手順を実行します。
pg:upgrade:prepare を実行して、リーダーデータベースのアップグレード準備を整え、次の利用可能なメンテナンスウィンドウ中にアップグレードをスケジュールします。- スケジュール済みのアップグレードのメンテナンスまで待つか、リーダーデータベースで
pg:upgrade:run を実行して、準備されたアップグレードを開始します。
pg:upgrade:dryrun コマンドを使用して、事前にバージョンアップグレードをテストできます。
1. バージョンアップグレードの準備をする
このコマンドは、フォロワーデータベースや Essential 層のデータベースは使用できません。これらのデータベースはメンテナンスウィンドウを通じてアップグレードされないためです。
はじめに、リーダーデータベースで pg:upgrade:prepare を実行します。
$ heroku pg:upgrade:prepare HEROKU_POSTGRESQL_RED --app example-app
このコマンドはアップグレードを準備し、次に利用可能なメンテナンスウィンドウにアップグレードのスケジュールを設定します。アップグレードの準備が整い、スケジュールが設定されると、メール通知が届きます。アップグレードの状況は pg:upgrade:wait または pg:info を使用して確認できます。たとえば、pg:upgrade:wait を使用します。
$ heroku pg:upgrade:wait HEROKU_POSTGRESQL_RED --app example-app
Waiting for database postgresql-crystalline-69217... ⣟ preparing service for upgrade
スケジュール済みのメンテナンスが始まる前、またはアップグレードを開始する前に、pg:upgrade:cancel を使用して、準備されたアップグレードをキャンセルすることができます。
2. バージョンアップグレードを実行する
アップグレード中はデータベースの接続が失われ、アプリはデータベースにアクセスできなくなります。さらに、Heroku Connect を使用して Salesforce データをデータベースと同期する場合、アップグレード中は Heroku Connect をデータベースに接続できません。同期プロセスが影響を受けた場合、接続は DB_UNAVAILABLE エラー状態になります。バージョンアップグレードの完了後に接続を回復して同期を再開するか、アップグレード開始前に Heroku Connect 接続を一時停止しておくと、DB_UNAVAILABLE 状態を回避することができます。
アップグレードの準備とスケジュール設定が完了したら、メンテナンスウィンドウまで待ってアップグレードが自動的に開始されるのを待つか、次のコマンドを使用して、リーダーデータベースでバージョンアップグレードを手動で開始することができます。
$ heroku pg:upgrade:run HEROKU_POSTGRESQL_RED --app example-app
アップグレードを開始した後はキャンセルできません。このコマンドは、接続されているフォロワーデータベースもアップグレードします。すべてのフォロワーをアップグレードするには、ある程度の時間がかかります。
アップグレードの状況は pg:upgrade:wait を使用して確認できます。
$ heroku pg:upgrade:wait HEROKU_POSTGRESQL_RED --app example-app
Waiting for database postgresql-crystalline-69217... ⣟ (1/8) checking upgrade service
Heroku Connect 接続を一時停止した場合は、必ずバージョンアップグレードが完了してから Heroku Connect 接続を再開してください。
フォロワーデータベースでのアップグレード
Postgres バージョンのアップグレード用の pg:upgrade CLI コマンドが変更されます。サポートが終了するまでは引き続き pg:upgrade も使用できますが、新しいアップグレードコマンドを使用して Postgres バージョンをアップグレードすることをお勧めします。詳細は、こちらのヘルプ記事を参照してください。
フォロワーデータベースでバージョンアップグレードを実行するには、データベースのフォロワーをアップグレードし、それを新しいアップグレードされたデータベースとして昇格させます。この方法では、別のアドオンでアップグレードを実行するため、アップグレード後も古いデータベースは引き続き使用できます。フォロワーデータベースでアップグレードを実行するには、約 30 分のアプリのダウンタイムが必要になります。
Postgres バージョンおよびプランの両方をアップグレードする必要がある場合は、別のプランで新しいフォロワーをプロビジョニングし、切り替えプロセスの一部として pg:upgrade:run を使用します。
この方法を使用すると、フォークされたデータベースで事前にバージョンアップグレードをテストできます。
Heroku Connect を使用して Salesforce データをデータベースと同期する場合は、フォロワーデータベースで Heroku Postgres のデータベースバージョンをアップグレードする手順を参照してください。
ストリーミングデータコネクターを使用する場合は、フォロワーデータベースで Heroku Postgres のデータベースバージョンをアップグレードする手順を参照してください。
1. フォロワーデータベースをプロビジョニングする
pg:upgrade:run を実行する 24 時間前までにアップグレード対象のフォロワーを作成することをお勧めします。
開始するには、データベースのフォロワーを作成し、そのフォロワーがリーダーデータベースに追いつくまで待ちます。この例では、standard-2 プランのフォロワーが HEROKU_POSTGRESQL_LAVENDER_URL に作成されます。ニーズに最適なプランをプロビジョニングできます。HEROKU_POSTGRESQL_LAVENDER_URLは、アップグレードしようとしているデータベースの環境設定に置き換えてください。
addons:create の例は Heroku CLI v9.0.0 以降の構文に従っています。v8.11.5 以前を使用している場合は、次のコマンドを使用してください。
$ heroku addons:create heroku-postgresql:standard-2 --follow HEROKU_POSTGRESQL_LAVENDER_URL --app example-app
$ heroku addons:create heroku-postgresql:standard-2 --app example-app -- --follow HEROKU_POSTGRESQL_LAVENDER_URL
Adding heroku-postgresql:standard-2 to example-app... done, v71 ($200/mo)
Attached as HEROKU_POSTGRESQL_WHITE
Follower will become available for read-only queries when up-to-date
Use `heroku pg:wait` to track status
$ heroku pg:wait
Waiting for database HEROKU_POSTGRESQL_WHITE_URL... performing final cleanup steps after upgrade
フォロワーは、プライマリデータベースまで 200 コミット以内のときに「追いついた」と見なされます。フォロワーのコミット数がどのくらい遅れているかは、pg:info コマンドを使用して確認できます(フォロワーデータベースの Behind By 行を参照)。
$ heroku pg:info --app example-app
=== HEROKU_POSTGRESQL_LAVENDER
Plan: Standard 0
Status: available
...
=== HEROKU_POSTGRESQL_WHITE
Plan: Standard 2
Status: available
...
Following: HEROKU_POSTGRESQL_LAVENDER (DATABASE_URL)
Behind By: 125 commits
2. データベースの書き込みを防止するためにメンテナンスモードにする
アップグレードプロセス中に、新しいデータは新しいデータベースに転送されないため、現在のプライマリデータベースに新しいデータが書き込まれないようにすることが重要です。これを行うには、アプリをメンテナンスモードにします。スケジューラージョブも実行されている場合は、これを無効にします。メンテナンスモードの間、データベースでは請求時間が発生し続けます。
メンテナンスモードでは、dyno が自動的にはスケールダウンされません。どの接続もデータベースにデータを書き込んでいないようにするために、Web dyno や Web 以外の dyno をスケールダウンします (heroku ps:scale worker=0 など)。
アップグレードプロセスのこの時点で、アプリケーションは起動できなくなります。
$ heroku maintenance:on --app example-app
Enabling maintenance mode for example-app... done
3. フォロワーデータベースをアップグレードする
メンテナンスモードになり、プライマリデータベースに追加データが書き込まれていない状態になったので、フォロワーデータベースをアップグレードできます。
フォロワーデータベースがプライマリに完全に追いつくまで (遅れが 0 commits と表示されるまで) 待ちます。
$ heroku pg:info --app example-app
=== HEROKU_POSTGRESQL_LAVENDER_URL
Plan: Standard 0
Status: available
...
=== HEROKU_POSTGRESQL_WHITE_URL
Plan: Standard 2
Status: available
...
Following: HEROKU_POSTGRESQL_LAVENDER_URL (DATABASE_URL)
Behind By: 0 commits
フォロワーが追いつくまで待たないと、次のエラーメッセージが表示されることがあります。
▸ database is too far behind its leader. Wait until your follower catches up with its leader and try again.
フォロワーが追いついたら、pg:upgrade:run コマンドを使用して、フォロワーの Postgres バージョンをその場でアップグレードします。アップグレードにより、フォロワーはプライマリデータベースのフォロー解除も行います。この手順は通常、完了するまでに約 20 分かかります。
$ heroku pg:upgrade:run HEROKU_POSTGRESQL_WHITE --app example-app
pg:upgrade:wait または pg:wait を使用して、アップグレードの進捗状況を監視できます。
$ heroku pg:upgrade:wait --app example-app
Waiting for database HEROKU_POSTGRESQL_WHITE_URL... performing final cleanup steps after upgrade
pg:upgrade:run プロセスの一部として、Heroku Postgres はデータベースに対して ANALYZEを実行します。このプロセスにより、データベースの統計が再計算され、バージョンアップグレードの後も Postgres クエリプランナーに確実に最新情報が保持されるようになります。すべての資格情報とカスタム資格情報も、アップグレードプロセスの一環としてローテーションされます。
pg:upgrade:run コマンドは、データベース内のテーブルのデータ型に互換性がないなどのエラーが原因で失敗する可能性があります。アップグレードに失敗した場合は、pg:upgrade:wait または pg:wait を実行すると、version upgrade error, check your Heroku email notifications for details が返されます。エラーを解決した後、アップグレードを再開できます。
5.0 より前のバージョンの Rails には、Postgres 10 以上との既知の互換性の問題があります。この問題を回避するには、Rails のバージョンをアップグレードするか、Rails の問題で推奨されているモンキーパッチを使用してください。
4. 新しいデータベースをプロモートまたはアタッチする
DATABASE_URL が以前のプライマリデータベースの環境設定だった場合は、pg:promote を使用して新しくアップグレードしたデータベースを新しい DATABASE_URL としてプロモートします。pg:promote では、新しい HEROKU_POSTGRESQL_<color>_URL 環境設定に割り当てられた、古いプライマリデータベースの代替アタッチメントが作成されます。このプロモーションプロセスによってリリースがトリガーされ、アプリが再起動されます。
$ heroku pg:promote HEROKU_POSTGRESQL_WHITE --app example-app
Promoting HEROKU_POSTGRESQL_WHITE_URL to DATABASE_URL... done
アプリはまだ新しいリクエストを受信していませんが、これで手順 1 で作成したフォロワーデータベースがアプリのプライマリデータベース (DATABASE_URL) になりました。
アップグレードするデータベースにデフォルトの DATABASE_URL とは異なる環境設定がある場合は、heroku addons:attach を使用して、必要なエイリアスまたはアタッチメント名で新しくアップグレードしたデータベースをプロモートします。元のプライマリデータベースが複数のアプリにアタッチされていた場合は、addons:attach を使用して新たにアップグレードされたデータベースをこれらのアプリにアタッチする必要があります。
プロモーションの後、元のプライマリデータベースのフォロワーは、新しいプライマリのフォローを自動的に開始するようにはなりません。
必要に応じて、新しいプライマリデータベースのフォロワーを作成してください。Heroku CLI v9.0.0 以降を使用している場合は、次のコマンドを実行します。
$ heroku addons:create heroku-postgresql:standard-0 -a example-app -- --follow DATABASE_URL
Heroku CLI v8.11.5 以前を使用している場合は、次のコマンドを実行します。
$ heroku addons:create heroku-postgresql:standard-0 --follow DATABASE_URL --app example-app
古いフォロワーが必要なくなったら、必ずプロビジョニング解除してください。
古いプライマリが接続プールを使用していて、デフォルト名の DATABASE_CONNECTION_POOL でアタッチされていた場合、プロモートにより、接続プーラーは同じ名前 DATABASE_CONNECTION_POOL で新しいプライマリに再アタッチされます。
デフォルト以外の名前のアタッチメントは再アタッチされません。新しいプライマリでも、古いプライマリと同じデフォルト以外の名前で接続プールを使用する場合は、新しいプライマリで接続プールをアクティブ化する必要があります。
$ heroku pg:connection-pooling:attach DATABASE_URL --as MY_DATABASE_CONNECTION_POOL -a example-app
5. メンテナンスモードを終了する
通常のアプリケーション操作を再開するには、Web 以外のすべての dyno をその元のレベルにスケーリングします (heroku ps:scale worker=1 など)。
最後に、メンテナンスモードをオフにします。
$ heroku maintenance:off --app example-app
これで、アップグレードされたデータベースインスタンスへのリクエストをアプリケーションが受信するようになりました。これは、heroku pg:info を実行することによって確認できます。DATABASE_URL で示されるデータベースはプライマリデータベースと見なされます。
Heroku Postgres データベースが Heroku アプリケーションに接続されていない場合は、HEROKU_POSTGRESQL_WHITE_URL を取得し、それをプライマリデータベースとして使用するようにアプリケーションを更新する必要があります。
pg:copy でのアップグレード
pg:copy のアップグレード方法では、PostgreSQL のネイティブなバックアップと復元ユーティリティを使用します。データベースバックアップをディスクに書き込む代わりに、バックアップデータを新しくプロビジョニングされたデータベースの復元プロセスに直接ストリーミングします。このプロセスによって肥大化 (データベース上の使用されなくなった行によって占有される余分な領域) を減らし、ディスク領域を節約できます。
pg:copy の方法では、現在のデータベースの GB あたり約 3 分のアプリのダウンタイムが必要ですが、この量はスキーマやデータベースプランによって大きく異なる場合があります。必要なダウンタイムは、アップグレードをテストする (非本番アプリケーションの新しいデータベース上でアップグレードプロセスを実行する) ことによって見積もることができます。
pg:copy の方法では、サポートされているすべての Heroku Postgres プランとバージョン間のアップグレードがサポートされています。pg:copy は、デフォルトの資格情報とそれがアクセスできるデータのみをコピーします。その他の資格情報と、それでしかアクセスできないデータはコピーされません。この方法を使用すると、事前にバージョンアップグレードをテストすることもできます。
スケジュール設定されたバックアップ機能を使用する Essential 層データベースの場合、Production 層のプランにアップグレードするとスケジュールは失われます。バックアップが失われないようにするには、アップグレード後にもう一度スケジュールを設定します。
1. 新しいデータベースをプロビジョニングする
目的のプランの新しい Heroku Postgres データベースをプロビジョニングします (次の例では、standard-0 プランが使用されていますが、ニーズに最適なプランをプロビジョニングする必要がある)。
$ heroku addons:create heroku-postgresql:standard-0 --app example-app
Adding heroku-postgresql:standard-0 on example-app... done, v122 ($50/mo)
The database should be available in 3-5 minutes
データベースを、サポートされている最新バージョン以外のバージョンの PostgreSQL にアップグレードする場合は、--version フラグ (--version 15 など) で使用するバージョンを指定してください。
Standard、Premium、および Private 層データベースのプロビジョニングには数分かかります。pg:waitコマンドを使用すると、プロビジョニングがいつ完了したかの通知を受け取ることができます。
$ heroku pg:wait -a example-app
Waiting for database HEROKU_POSTGRESQL_PINK_URL... performing final cleanup steps after upgrade
2. データベースの書き込みを防止するためにメンテナンスモードにする
アップグレードプロセス中に、新しいデータは新しいデータベースに転送されないため、現在のプライマリデータベースに新しいデータが書き込まれないようにすることが重要です。これを行うには、アプリをメンテナンスモードにします。スケジューラージョブも実行されている場合は、これを無効にします。
メンテナンスモードでは、dyno が自動的にはスケールダウンされません。どの接続もデータベースにデータを書き込んでいないようにするために、Web dyno や Web 以外の dyno をスケールダウンします (heroku ps:scale worker=0 など)。
アップグレードプロセスのこの時点で、アプリケーションは起動できなくなります。
$ heroku maintenance:on -a example-app
Enabling maintenance mode for example-app... done
3. データを新しいデータベースに転送する
データを現在のデータベースから新しくプロビジョニングされたデータベースにコピーするには、新しいデータベースの HEROKU_POSTGRESQL_COLOR 名を指定して pg:copy コマンドを使用します。
この例では、DATABASE_URL が転送するデータのソースであり、HEROKU_POSTGRESQL_PINK がターゲットデータベースです。
$ heroku pg:copy DATABASE_URL HEROKU_POSTGRESQL_PINK --app example-app
! WARNING: Destructive Action
! Transfering data from DATABASE_URL to HEROKU_POSTGRESQL_PINK
! This command will affect the app: example-app
! To proceed, type "example-app" or re-run this command with --confirm example-app
> example-app
新しいデータベースのアドオン名 (例: postgresql-concave-52656) も使用できます。
$ heroku pg:copy DATABASE_URL postgresql-concave-52656 --app example-app
4. 新しいデータベースをプロモートまたはアタッチする
DATABASE_URL が以前のプライマリデータベースの環境設定だった場合は、pg:promote を使用して新しくアップグレードしたデータベースを新しい DATABASE_URL としてプロモートします。pg:promote では、新しい HEROKU_POSTGRESQL_<color>_URL 環境設定に割り当てられた、古いプライマリデータベースの代替アタッチメントが作成されます。このプロモーションプロセスによってリリースがトリガーされ、アプリが再起動されます。
$ heroku pg:promote HEROKU_POSTGRESQL_PINK --app example-app
Promoting HEROKU_POSTGRESQL_PINK_URL to DATABASE_URL... done
アプリはまだ新しいリクエストを受信していませんが、これで手順 1 で作成したデータベースがアプリのプライマリデータベース (DATABASE_URL) になりました。
アップグレードするデータベースにデフォルトの DATABASE_URL とは異なる環境設定がある場合は、heroku addons:attach を使用して、必要なエイリアスまたはアタッチメント名で新しくアップグレードしたデータベースをプロモートします。元のプライマリデータベースが複数のアプリにアタッチされていた場合は、addons:attach を使用して新たにアップグレードされたデータベースをこれらのアプリにアタッチする必要があります。
プロモーションの後、元のプライマリデータベースのフォロワーは、新しいプライマリのフォローを自動的に開始するようにはなりません。
必要に応じて、新しいプライマリデータベースのフォロワーを作成してください。Heroku CLI v9.0.0 以降を使用している場合は、次のコマンドを実行します。
$ heroku addons:create heroku-postgresql:standard-0 -a example-app -- --follow DATABASE_URL
Heroku CLI v8.11.5 以前を使用している場合は、次のコマンドを実行します。
$ heroku addons:create heroku-postgresql:standard-0 --follow DATABASE_URL -a example-app
古いフォロワーが必要なくなったら、必ずプロビジョニング解除してください。
5. メンテナンスモードを終了する
通常のアプリケーション操作を再開するには、Web 以外のすべての dyno をその元のレベルにスケーリングします (heroku ps:scale worker=1 など)。
最後に、メンテナンスモードをオフにします。
$ heroku maintenance:off --app example-app
アプリケーションが、新しいデータベースインスタンスへのリクエストを受信するようになりました。これは、heroku pg:info を実行することによって確認できます。DATABASE_URL で示されるデータベースはプライマリデータベースと見なされます。
Heroku Postgres データベースが Heroku アプリケーションに接続されていない場合は、HEROKU_POSTGRESQL_WHITE_URL を取得し、それをプライマリデータベースとして使用するようにアプリケーションを更新する必要があります。
古いプライマリデータベースのプロビジョニング解除
データベースをアップグレードした後、古いプライマリデータベースを必ずプロビジョニング解除してください。
$ heroku addons:destroy HEROKU_POSTGRESQL_LAVENDER --app example-app
古いプライマリデータベースに関連付けられていたデータクリップを新しいデータベースに再割り当てする必要があります。すべての回復可能なデータクリップを解決するには、「Dataclip recovery」(データクリップのリカバリ) の手順に従ってください。