Heroku Postgres
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2019年07月25日(木)
Table of Contents
Heroku Postgres は、Heroku が直接提供するマネージド SQL データベースサービスです。PostgreSQL ドライバーを使用して、Heroku が公式にサポートするすべての言語を含むどの言語の Heroku Postgres データベースにもアクセスできます。
Heroku CLI から使用できるさまざまな管理コマンドに加え、Heroku Postgres には、Web ダッシュボード、データクリップとクエリを共有する機能、およびその他の複数の役立つ機能が用意されています。
Heroku Postgres のプロビジョニング
Heroku Postgres をプロビジョニングする前に、まだアプリに対してプロビジョニングされていないことを確認します (Heroku は自動的に、pg
Ruby gem などの特定のライブラリを含むアプリに対して Postgres をプロビジョニングします)。
heroku addons
コマンドを使用して、アプリがすでに Heroku Postgres をプロビジョニングしているかどうかを判定します。
$ heroku addons
Add-on Plan Price State
────────────────────────────────────────────────────────── ───────── ───── ───────
heroku-postgresql (postgresql-concave-52656) hobby-dev free created
heroku-postgresql
に、アプリのアドオンリストが表示されていない場合は、次の CLI コマンドでプロビジョニングできます。
$ heroku addons:create heroku-postgresql:<PLAN_NAME>
たとえば、hobby-dev プランデータベースをプロビジョニングするには、次のように実行します。
$ heroku addons:create heroku-postgresql:hobby-dev
Creating heroku-postgresql:hobby-dev on ⬢ sushi... free
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-concave-52656 as DATABASE_URL
プロビジョニングコマンドに --version
フラグを含めることで、プロビジョニングする Postgres のバージョンを指定できます。
$ heroku addons:create heroku-postgresql:<PLAN_NAME> --version=9.5
PostgreSQL バージョンのサポートの詳細を確認してください。
選択したプランに応じて、データベースは使用可能になるまでに最長 5 分かかることがあります。heroku pg:wait
コマンドでステータスを追跡できます。このコマンドは、データベースが使用できるようになるまでブロックします。
プロビジョニングプロセスの一部として、DATABASE_URL
環境設定がアプリの設定に追加されます。これには、アプリがデータベースへのアクセスに使用する URL が含まれます。アプリにすでに Heroku Postgres データベースがあり、別のものをプロビジョニングした場合、この環境設定の名前は、代わりに HEROKU_POSTGRESQL_<COLOR>_URL
の形式 (たとえば HEROKU_POSTGRESQL_YELLOW_URL
) になります。
heroku config
コマンドで、アプリの環境設定の名前および値を確認できます。
アプリの DATABASE_URL
環境設定の値は、随時変更する可能性があります。
Heroku アプリの内部または外部のどちらでもこの値を信頼しないでください。
この時点で、空の PostgreSQL がプロビジョニングされます。既存のデータソースからデータを入力するには、インポート手順を参照するか、この記事の言語固有の手順に従って、アプリケーションから接続してください。
Heroku Postgres プランについて
Heroku Postgres は、Hobby、Standard、Premium、Enterprise というサービスの異なる層にまたがる、さまざまなプランを提供しています。 各プランが提供する内容の詳細については、「Choosing the Right Heroku Postgres Plan」(適切な Heroku Postgres プランの選択) を参照してください。
Heroku Postgres プランの価格情報は、Heroku Postgres アドオンページで確認できます。
アプリの要件が最終的に、選択した初期プランで提供されたリソースより大きくなりすぎた場合、簡単にデータベースをアップグレードできます。
プライマリデータベースの指定
Heroku アプリは、DATABASE_URL
環境変数を使用して、アプリのプライマリデータベースの URL を指定します。アプリにデータベースが 1 つしかない場合、URL は自動的にこの環境設定に割り当てられます。
複数のデータベースを持つアプリの場合、heroku pg:promote
コマンドでプライマリデータベースを設定できます。
$ heroku pg:promote HEROKU_POSTGRESQL_YELLOW
Promoting HEROKU_POSTGRESQL_YELLOW_URL to DATABASE_URL... done
プロモートするデータベースに関連付けられた「カラー」識別子またはアドオン名を指定できます。
アプリケーション間での Heroku Postgres の共有
heroku addons:attach
コマンドを使用して、単一の Heroku Postgres データベースを複数のアプリ間で共有できます。
$ heroku addons:attach my-originating-app::DATABASE --app sushi
Attaching postgresql-addon-name to sushi... done
Setting HEROKU_POSTGRESQL_BRONZE vars and restarting sushi... done, v11
アタッチされたデータベースの URL は、名前形式 HEROKU_POSTGRESQL_[COLOR]_URL
で環境設定に割り当てられます。上記の例では、環境設定の名前は HEROKU_POSTGRESQL_BRONZE_URL
です。
共有されたデータベースは必ずしも、共有するどのアプリにとってもプライマリデータベースになるわけではありません。他のデータベースに使用した同じコマンドで、共有されたデータベースをプロモートします。
heroku addons:detach
コマンドを使用して、別のアプリとの Heroku Postgres インスタンスの共有を停止できます。
$ heroku addons:detach HEROKU_POSTGRESQL_BRONZE --app sushi
Detaching HEROKU_POSTGRESQL_BRONZE to postgresql-addon-name from sushi... done
Unsetting HEROKU_POSTGRESQL_BRONZE config vars and restarting sushi... done, v11
バージョンのサポート
PostgreSQL プロジェクトは毎年、新しいメジャーバージョンをリリースします。それぞれのメジャーバージョンは、リリースの直後に Heroku Postgres によってサポートされます。
Heroku Postgres は、その時々で少なくとも 3 つのメジャーバージョンをサポートしています。現在サポートされているバージョンは次のとおりです。
- 11 (デフォルト)
- 10
- 9.6
- 9.5
- 9.4 - 非推奨
ユーザーは、およそ 3 年に 1 度アップグレードするように要求されます。ただし、どの時点でもデータベースをアップグレードして最新バージョンの利点を受けられます。
非推奨のデータベースの移行
PostgreSQL プロジェクトは、最初のリリースから 5 年後に、メジャーバージョンのサポートを停止します。Heroku Postgres は、これらのバージョンを非推奨にして、PostgreSQL のサポートされていないメジャーバージョンでデータベースが実行しないようにします。
- バージョンのサポート終了 (EOL) の 1 年前に、Heroku は、非推奨バージョンでの新しいデータベースへのプロビジョニングを止めます (既存のデータベースのフォークおよびフォロワーはまだ許容されます)。
- EOL の 6 か月前に、アップグレードする必要があるという通知と、自身のスケジュールでアップグレードを行う方法に関する説明がお客様に送られます。
- EOL の 3 か月前に、残りのすべてのデータベースの強制アップグレードメンテナンスをスケジュールします。
Heroku は、サポートが終了する前にバージョンアップグレードまたは更新を実行して、自身のスケジュールで互換性のテスト、予期しない問題の対策、データベースの移行を行えるようにすることを強くお勧めします。
従来のインフラストラクチャ
Heroku は、場合によっては、インフラストラクチャの古いバージョンも非推奨にします。これは通常、次のいずれかの理由で行われます。
- データベースの下で実行しているオペレーティングシステムは、すぐにセキュリティ更新を受けないようになります。
- オペレーティングシステムのサポートは、その経過年数により (必要なパッケージおよびパッチが利用できなくなったり、サポートが困難になった場合) 実用的でなくなります。
- サーバーインスタンスは、Heroku の現在のインフラストラクチャとは大きく異なり、サポートは非現実的です。
データベースが従来のインフラストラクチャで実行しているかどうかを確認するには、pg:info
を使用します。
$ heroku pg:info
=== HEROKU_POSTGRESQL_MAROON_URL (DATABASE_URL)
Plan: Ronin
Status: Available
Data Size: 26.1 MB
Tables: 5
PG Version: 9.5.3
Connections: 2
Fork/Follow: Available
Rollback: Unsupported
Created: 2012-05-02 21:54 UTC
Maintenance: not required (Mondays 23:00 to Tuesdays 03:00 UTC)
Infrastructure: Legacy
パフォーマンス分析
パフォーマンス分析は、Heroku Postgres の可視性スイートです。これを使用すると、データベースのパフォーマンスを監視して、潜在的な問題を診断できます。次の複数のコンポーネントから構成されています。
高コストなクエリ
低いデータベースパフォーマンスの主な原因は、クエリが最適化されていないことです。data.heroku.com で入手できる最も高コストのクエリのリストは、データベースで最も時間のかかるクエリを特定し把握するときに役立ちます。完全なドキュメントはここで使用できます。
ログ記録
アプリケーション/フレームワークがデータベースアクセスのログを出力する場合、Heroku のログストリームからそれらのログを取得できます。
$ heroku logs -t
データベースサービス自体からログを表示するには、heroku logs
を -p postgres
オプションとともに使用して、Postgres からのログだけを表示します。
$ heroku logs -p postgres -t
データベースパフォーマンスへの影響を最小限に抑えるために、ログはベストエフォートで配信されます。
詳細は、「Heroku Postgres log statements」(Heroku Postgres のログ文) を参照してください。
pg:diagnose
pg:diagnose
は、データベースのパフォーマンスの分析と最適化に役立つ、多数の有用なヘルスおよび診断チェックを実行します。チームメイトや Heroku サポートと共有できるレポートが生成されます。
レポートに基づいて何らかの措置を講じる前に、必ずデータベースおよびアプリケーションへの影響を慎重に検討してください。
$ heroku pg:diagnose --app sushi
Report 1234abc… for sushi::HEROKU_POSTGRESQL_MAROON_URL
available for one month after creation on 2014-07-03 21:29:40.868968+00
GREEN: Connection Count
GREEN: Long Queries
GREEN: Long Transactions
GREEN: Idle in Transaction
GREEN: Indexes
GREEN: Bloat
GREEN: Hit Rate
GREEN: Blocking Queries
GREEN: Sequences
GREEN: Table Transaction ID Wraparound
GREEN: Database Transaction ID Wraparound
GREEN: Schema Count
GREEN: Load
チェック: 接続数
各 Postgres 接続には、メモリが必要であり、データベースプランには、受け入れられる接続数に制限があります。非常に多くの接続を使用している場合は、PgBouncer などの接続プーラーを使用するか、RAM を増やしたより大きなプランに移行することを検討してください。
チェック: 長時間実行クエリ、長時間トランザクション、トランザクション内部での待ち状態
長時間実行クエリおよびトランザクションは、自動バキュームを妨げ、フォロワーを遅らせる肥大化の問題を起こす可能性があります。また、データにロックが作成され、このため他のトランザクションが実行できなくなります。pg:kill
で長時間実行クエリを強制終了することを検討してください。
idle in transaction
であるバックエンドは、COMMIT;
または ROLLBACK
のどちらかを通じてクライアントがトランザクションを終了するまで待機するバックエンドです。不適切に切断されたクライアントは、バックエンドをこの状態のままにすることがあり、開かれたままの場合は pg:kill --force
で強制終了する必要があります。
チェック: インデックス
インデックスチェックには、3 つのクラスのインデックスが含まれます。Never Used Indexes (使用歴のないインデックス) は、使用されたことがありません (前回の手動データベース統計の更新後)。これらのインデックスは通常、フォロワーで使用されている場合以外は、破棄しても問題ありません。
Low Scans, High Writes (低スキャン、高書き込み) インデックスは、使用されているが、書き込みボリュームに比べて頻度が高くありません。インデックスは、すべての書き込みで更新されるので、高書き込みテーブルで特にコストが大きくなります。これらのインデックスによって得られるパフォーマンスの向上に対して、書き込み速度の低下のコストを考慮してください。
Seldom used Large Indexes (めったに使用されない大きなインデックス) は、あまり使用されておらず、ディスク上およびキャッシュ (RAM) 内の両方で大きな領域を占めます。これらのインデックスは、たとえば定期的なジョブや頻度の少ないトラフィックパターンで使用される場合など、依然としてアプリケーションにとって重要であることがあります。
インデックスの使用状況は、クエリを受信するデータベースでのみ追跡されます。読み取りにフォロワーを使用している場合は、このチェックは、フォロワーに対して行われた使用は明らかにせず、不正確になる可能性が高いです。
チェック: 肥大化
Postgres は MVCC を使用するので、旧バージョンの更新済みまたは削除済みの行は、その場で修正されるのではなく、単に非表示になるだけです。通常の操作では、自動バキュームプロセスが行われ、非同期的にこれらを消去します。ただし、十分高速に機能できなかったり、それ以外では一部のテーブルの肥大化を防止できなかったりすることがあります。肥大化が高くなると、データベースが使用されなくなった行を調べるのにより多くの時間を費やすため、クエリの速度を低下し、領域を浪費し、負荷を増大させることがあります。psql
内の VACUUM (VERBOSE, ANALYZE);
コマンドでテーブルを手動でバキュームできます。これが頻繁に発生する場合、自動バキュームをより活動的なものにすることができます。
json
列など、列統計値のない列を使用するテーブルでは、肥大化評価計算が正確でない場合があることに注意してください。これは特に Postgres 9.4 以下で顕著です。
チェック: ヒット率
これは、全体のインデックスヒット率、全体のキャッシュヒット率、およびテーブルあたりの個々のインデックスヒット率をチェックします。キャッシュヒット率が低下したデータベースは、メモリから読み取る代わりに、ディスクをヒットする必要があるので、パフォーマンスが大幅に劣化します。キャッシュヒット率が低い場合はより大きなプランへ移行することを、インデックスヒット率が低い場合は適切なインデックスを追加することを検討してください。全体のキャッシュヒット率が、ディスクから読み取られたキャッシュ済みブロックと未キャッシュブロックの合計と比べた、Postgres バッファキャッシュから取得されたテーブルデータブロックの比率として計算されます。より大きなプランでは、キャッシュヒットの比率が低下することがありますが、残りのデータが Postgres ではなく OS によってメモリにキャッシュされるので、パフォーマンスは一定です。
全体のインデックスヒット率が、ディスクから読み取られたインデックス済みブロックと未インデックスブロックの合計と比べた、Postgres バッファキャッシュから取得されたインデックスブロックの比率として計算されます。より大きなプランでは、インデックスヒットの比率が低下することがありますが、残りのインデックスデータが Postgres ではなく OS によってメモリにキャッシュされるので、パフォーマンスは一定です。
テーブルあたりの個々のインデックスヒット率は、テーブルに対するシーケンシャルスキャンとインデックススキャンの合計と比較した、テーブルに対するインデックススキャンの比率として計算されます。
チェック: クエリのブロック
一部のクエリは、他のクエリが実行しないようにするロックをかけることがあります。通常、これらのロックは非常に迅速に取得および解除され、問題を起こしません。ただし、異常な状況では、一部のクエリは、長時間保持された場合に重大な問題を引き起こすため、ロックをかけることがあります。pg:kill
でクエリを強制終了することもできます。
チェック: シーケンス
これは、関連付けられたシーケンスを持つ 32 ビット integer
(aka int4) 列を調べ、32 ビット int の最大値に近づいた列について報告します。オーバーフローを避けるため、これらの列を 64 ビット bigint
(aka int8) 列に移行する必要があります。このような移行の例が alter table products alter column id type bigint;
です。列タイプを変更すると、コストのかかる操作になることがあり、この場合、大きなテーブルでこれに応じた十分なプランニングを行う必要があります。
64 ビットシステムでのアラインメントの考慮事項のために、Heroku Postgres で integer
列を bigint
列よりも優先させる理由はありません (複合インデックスは除く)。
このチェックは、100 以上の integer
(int4) 列がある場合、スキップされます。
チェック: テーブルトランザクション ID ラップアラウンド、データベーストランザクション ID ラップアラウンド
これらのチェックは、個々のテーブルまたはデータベースが、トランザクション ID ラップアラウンドにどれだけ近づいているかを判断します。これは、自動バキューム操作が、非常に頻繁に更新されるテーブルの動向を把握できないために、これらのテーブルは、そのテーブル (またはデータベース) のトランザクション ID がラップしてデータの損失を招く危険があるという非常に珍しいシナリオです。これを避けるために、Postgres は、解決されるまでクラスター全体で新しい書き込みを防止するので、可用性に影響します。これらのチェックは、トランザクション ID 領域の 50% 以上が使用されている場合、テーブル名およびデータベース名を返します。
チェック: スキーマ数
このチェックは、データベース内に存在するスキーマの数を数え、19 以上のスキーマには黄色の警告を、50 以上のスキーマには赤色の警告を返します。スキーマが非常に多数の場合、Postgres のパフォーマンスと正常な論理バックアップを取得する機能に大きな影響が及ぶ可能性があるので、50 スキーマ以下に抑えることをお勧めします。
チェック: 負荷
負荷がデータベースで高くなる理由には、肥大化、CPU 集約的クエリ、インデックスビルド、データベースでの単に過剰なアクティビティなど多数あります。アクセスパターンを確認し、より強力なプロセッサーのあるより大きなプランへの移行を検討してください。
ローカルの設定
- Mac の設定
- Windows の設定
- Linux の設定
Heroku では、Postgres をローカルで実行して環境間でのパリティを確保することをお勧めします。ローカル環境で PostgreSQL をインストールするための複数の事前にパッケージ化されたインストーラーがあります。
Postgres がインストールされ接続できるようになると、ローカルで実行するときにアプリが接続できるように、DATABASE_URL 環境変数をエクスポートする必要があります。
-- for Mac and Linux
$ export DATABASE_URL=postgres://$(whoami)
-- for Windows
$ set DATABASE_URL=postgres://$(whoami)
これは、Postgres に、ユーザーアカウント名 (インストールの一部として設定) に一致するデータベースにローカルで接続するように指示します。
Postgres on Mac の設定
Postgres.app は Mac OS 10.7 以上を必要とします。
- Postgres.app をインストールし、設定手順に従います。
- Postgres CLI ツールをインストールします。
- 新しいターミナルウィンドウを開いて、変更内容が保存されたことを確認します。
- 正しく機能したことを確かめます。OS X バージョンの
psql
は、Postgres.app
ディレクトリを含むパスを示している必要があります。
バージョン 9.5 を使用している場合、出力は次のようになります。
$ which psql
/Applications/Postgres.app/Contents/Versions/latest/bin/psql
次のコマンドは正しく機能します。
$ createdb
$ psql -h localhost
psql (9.5.2)
Type "help" for help.
=# \q
アプリはログイン時に自動的に開始するように設定されていることも確認します。
PostgreSQL には、使用したいと思えるような pg_dump
や pg_restore
などの複数の有用なバイナリが付属しています。Postgres.app を含んだ /bin
ディレクトリを PATH に追加します (これがすべてのターミナルセッションに対して設定されるように、できれば .profile
、.bashrc
、.zshrc
などで追加します)。
PATH="/Applications/Postgres.app/Contents/Versions/latest/bin:$PATH"
Postgres on Windows の設定
Windows インストーラーを使用して、Postgres on Windows をインストールします。
必ず、Postgres インストールの bin
ディレクトリを追加するように、PATH 環境変数を更新してください。ディレクトリは、C:\Program Files\PostgreSQL\<VERSION>\bin
のようになります。PATH を更新し忘れた場合は、heroku pg:psql
などのコマンドが機能しなくなります。
Postgres on Linux の設定
パッケージマネージャから Postgres をインストールします。実際に使用するパッケージマネージャコマンドは、ディストリビューションによって異なります。次のコマンドは、Ubuntu、Debian、および他の Debian 派生ディストリビューションで機能します。
$ sudo apt-get install postgresql
ディストリビューションに Postgres パッケージマネージャがないか、Postgres パッケージが利用できない場合は、いずれかの汎用インストーラーを使用して Postgres on Linux をインストールします。
psql
クライアントは通常、/usr/bin
にインストールされます。
$ which psql
/usr/bin/psql
次のコマンドは正しく機能します。
$ psql
psql (9.3.5)
Type "help" for help.
maciek# \q
CLI の使用
Heroku Postgres は、Heroku CLI に直接統合され、一般的なデータベースタスクを簡略化する多くの役立つコマンドを提供します。
pg:info
アプリケーションによりプロビジョニングされるすべての PostgreSQL データベースと、それぞれの識別特性 (データベースサイズ、ステータス、テーブル数、PG バージョンなど) を確認するには、heroku pg:info
コマンドを使用します。
$ heroku pg:info
=== HEROKU_POSTGRESQL_RED
Plan Standard 0
Status available
Data Size 82.8 GB
Tables 13
PG Version 9.5.3
Created 2012-02-15 09:58 PDT
=== HEROKU_POSTGRESQL_GRAY
Plan Standard 2
Status available
Data Size 82.8 GB
…
データベースのステータスを継続的に監視するには、Unix Watch コマンドを通じて pg:info
を渡します。
$ watch heroku pg:info
pg:psql
psql
は、ネイティブの PostgreSQL 対話型ターミナルであり、クエリを実行し、接続されたデータベースにコマンドを発行するために使用されます。
リモートデータベースとの psql
セッションを確立するには、heroku pg:psql
を使用します。
heroku pg:psql
を使用するには、PostgreSQL がシステムにインストールされている必要があります。
$ heroku pg:psql
Connecting to HEROKU_POSTGRESQL_RED... done
psql (9.5.3, server 9.5.3)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.
rd2lk8ev3jt5j50=> SELECT * FROM users;
複数のデータベースがある場合、コマンドへの最初の引数として、接続先のデータベース (色だけが省略表現として機能) を指定します (DATABASE_URL
にあるデータベースがデフォルトで使用されます)。
$ heroku pg:psql gray
Connecting to HEROKU_POSTGRESQL_GRAY... done
...
pg:push および pg:pull
バックアップの操作に関する詳細なガイドについては、インポートとエクスポートのガイドを参照してください。
pg:pull
pg:pull
は、Heroku Postgres データベースからローカルマシン上のデータベースにリモートデータをプルするために使用できます。コマンドは次のようになります。
$ heroku pg:pull HEROKU_POSTGRESQL_MAGENTA mylocaldb --app sushi
このコマンドは、mylocaldb
という新しいローカルデータベースを作成し、続いてアプリ sushi
から、DATABASE_URL
にあるデータベースのデータをプルします。誤ってデータが上書きされたり失われることがないように、ローカルデータベースはまだ存在してはなりません。続行する前に、すでに存在しているローカルデータベースを破棄するように求められます。
ローカル DB に Postgres ユーザーまたはパスワードを提供する必要がある場合は、次のような適切な環境変数を使用します。
$ PGUSER=postgres PGPASSWORD=password heroku pg:pull HEROKU_POSTGRESQL_MAGENTA mylocaldb --app sushi
すべての pg:*
コマンドと同様に、ここでは省略表現のデータベース識別子を使用できます。たとえば、アプリ sushi
上の HEROKU_POSTGRESQL_RED
からデータをプルするには、heroku pg:pull sushi::RED mylocaldb
を実行できます。
pg:push
pg:push
は、リモート Heroku Postgres データベースにローカルデータベースからのデータをプッシュします。コマンドは次のようになります。
$ heroku pg:push mylocaldb HEROKU_POSTGRESQL_MAGENTA --app sushi
このコマンドは、ローカルデータベース mylocaldb
を選んで、アプリ sushi
の DATABASE_URL
にあるデータベースにプッシュします。誤ってデータが上書きされたり失われることがないように、リモートデータベースは空である必要があります。空でないリモートデータベースには pg:reset
を行うように求められます。
ローカルデータベースに対する PGUSER
および PGPASSWORD
の使用は、pg:pull
コマンドの場合と同様に、pg:push
でもサポートされています。
トラブルシューティング
これらのコマンドは、Postgres インストールに含まれている pg_dump
バイナリと pg_restore
バイナリにより異なります。ただし、正しくないバイナリを $PATH
に読み込むことはときどき発生します。たとえば
! createdb: could not connect to database postgres: could not connect to server: No such file or directory
! Is the server running locally and accepting
! connections on Unix domain socket "/var/pgsql_socket/.s.PGSQL.5432"?
!
! Unable to create new local database. Ensure your local Postgres is working and try again.
や
pg_dump: server version: 9.5.3; pg_dump version: 9.5.3
pg_dump: aborting because of server version mismatch
pg_dump: *** aborted because of error
pg_restore: [archiver] input file is too short (read 0, expected 5)
のようなエラーはどちらも、多くの場合、この正しくない $PATH
の問題の結果です。/Applications/Postgres.app/Contents/MacOS/bin
を $PATH
に追加するインストール前のステップは忘れやすいので、この問題は、特に Postgres.app ユーザーによく見られます
pg:ps、pg:kill、pg:killall
これらのコマンドを使用すると、現在実行しているクエリを表示して管理できます。
pg:ps
コマンドは Postgres 内の pg_stat_activity
ビューをクエリして、現在実行しているクエリに対する簡潔なビューを表示します。
$ heroku pg:ps
procpid | source | running_for | waiting | query
---------+---------------------------+-----------------+---------+-----------------------
31776 | psql | 00:19:08.017088 | f | <IDLE> in transaction
31912 | psql | 00:18:56.12178 | t | select * from hello;
32670 | Heroku Postgres Data Clip | 00:00:25.625609 | f | BEGIN READ ONLY; select 'hi'
(3 rows)
その場合、これらのクエリを pg:kill
でキャンセルまたは強制終了するために、procpid 列を使用できます。引数を使用しない場合、pgcancelbackend が、クエリをキャンセルしようとするクエリで呼び出されます。これは状況によっては失敗することがあります。この場合、--force
オプションを使用して、そのクエリの接続全体を切断する pg\_terminate_backend を発行できます。
$ heroku pg:kill 31912
pg_cancel_backend
-------------------
t
(1 row)
$ heroku pg:kill --force 32670
pg_terminate_backend
----------------------
t
(1 row)
pg:killall
は pg:kill
に似ていますが、データベースのすべてのクエリをキャンセルまたは強制終了します。
pg:promote
複数のデータベースがプロビジョニングされる設定では (一般的なユースケースにはマスター/スレーブ高可用性設定やデータベースアップグレードプロセス)の一部が含まれます)、多くの場合、プライマリロールに補助的データベースをプロモートすることが必要になります。これは、heroku pg:promote
コマンドで行います。
$ heroku pg:promote HEROKU_POSTGRESQL_GRAY_URL
Promoting HEROKU_POSTGRESQL_GRAY_URL to DATABASE_URL... done
pg:promote
を機能させるには、DATABASE_URL
環境設定の値 (アプリケーションがプライマリデータベースに接続するために使用します) を、新しくプロモートしたデータベースの URL に設定し、アプリを再起動します。古いプライマリデータベースの場所には、その HEROKU_POSTGRESQL_COLOR_URL
設定を介して引き続きアクセスできます。
プロモーション後、デモートしたデータベースは引き続きプロビジョニングされ、料金が発生します。必要なくなった場合は、heroku addons:destroy HEROKU_POSTGRESQL_COLOR
で削除できます。
pg:credentials
Heroku Postgres は、GUI を使用してインスタンスにアクセスする必要がある場合に、データベースの資格情報および場所への便利なアクセスを提供します。
データベース名の引数を pg:credentials:url
コマンドに与える必要があります。プライマリデータベースには DATABASE
を使用します。
$ heroku pg:credentials:url DATABASE
Connection info string:
"dbname=dee932clc3mg8h host=ec2-123-73-145-214.compute-1.amazonaws.com port=6212 user=user3121 password=98kd8a9 sslmode=require"
セキュリティ上、重要なサービスの資格情報は定期的に変更することをお勧めします。Heroku Postgres でこれを行うには heroku pg:credentials:rotate
を使用します。
$ heroku pg:credentials:rotate HEROKU_POSTGRESQL_GRAY_URL
このコマンドを発行すると、データベースの新しい資格情報が作成され、Heroku アプリケーションでの関連した環境設定が更新されます。ただし、Standard、Premium、および Enterprise 層のデータベースでは、古い資格情報はすぐには削除されません。開いている接続はすべて、現在実行中のタスクが終了するまで開いたままになり、その後、これらの資格情報は更新されます。これは、本番環境で実行しているバックグラウンドジョブや他の Worker が突然強制終了されないようにするためです。突然強制終了されると、システムが不整合な状態になる可能性があります。
pg:reset
データベースが割り当てられた PostgreSQL ユーザーには、データベースを作成または破棄する権限がありません。データベースを破棄して作成し直すには、pg:reset
を使用します。
$ heroku pg:reset DATABASE
Heroku Postgres および SSL
ほとんどのクライアントはデフォルトで SSL で接続しますが、Postgres 接続で sslmode=require
パラメータを設定する必要がある場合もあります。環境設定を直接編集するのではなく、コードにこのパラメータを追加してください。特に Java クライアントまたは Node.js クライアントを使用している場合は、SSL の使用を強制していることを確認してください。
Java での接続
ご使用の Java フレームワークに応じて、Heroku Postgres データベースへの接続を作成するさまざまな方法があります。「Java を使用して Heroku でリレーショナルデータベースに接続する」の記事に記述されているように、ほとんどの場合、環境変数 JDBC_DATABASE_URL
は直接使用できます。次に例を示します。
private static Connection getConnection() throws URISyntaxException, SQLException {
String dbUrl = System.getenv("JDBC_DATABASE_URL");
return DriverManager.getConnection(dbUrl);
}
JDBC URL を使用することができない場合 (通常、カスタム buildpack が使用されているため)、DATABASE_URL
環境の URL を使用して、接続情報を特定する必要があります。いくつかの例を下に示します。
デフォルトで、Heroku は、プロパティ sslmode=require
をグローバルで設定することによって、PostgreSQL JDBC ドライバーに対して SSL を有効にしようとします。ただし、JDBC URL を自身でビルドしている場合 (DATABASE_URL
の解析によってなど)、このパラメータを明示的に追加することをお勧めします。
Postgres JDBC ドライバーバージョン 9.2 以上のバージョンを使用することも重要です。たとえば、Maven で次を pom.xml
に追加します。
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.1</version>
</dependency>
ここで概説するすべての接続方法の例は、https://github.com/heroku/devcenter-java-database にある GitHub で入手できます。
JDBC
DATABASE_URL
環境変数を解析することにより、Heroku Postgres への JDBC 接続を作成します。
private static Connection getConnection() throws URISyntaxException, SQLException {
URI dbUri = new URI(System.getenv("DATABASE_URL"));
String username = dbUri.getUserInfo().split(":")[0];
String password = dbUri.getUserInfo().split(":")[1];
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + dbUri.getPath() + "?sslmode=require";
return DriverManager.getConnection(dbUrl, username, password);
}
Spring/XML
Spring XML 設定のこのスニペットは、DATABASE_URL
から BasicDataSource
を設定し、その後 Hibernate や JPA などで使用できます。
<bean class="java.net.URI" id="dbUrl">
<constructor-arg value="#{systemEnvironment['DATABASE_URL']}"/>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="#{ 'jdbc:postgresql://' + @dbUrl.getHost() + ':' + @dbUrl.getPort() + @dbUrl.getPath() + '?sslmode=require' }"/>
<property name="username" value="#{ @dbUrl.getUserInfo().split(':')[0] }"/>
<property name="password" value="#{ @dbUrl.getUserInfo().split(':')[1] }"/>
</bean>
Spring/Java
または、Spring で BasicDataSource
の設定に Java を使用できます。
@Configuration
public class MainConfig {
@Bean
public BasicDataSource dataSource() throws URISyntaxException {
URI dbUri = new URI(System.getenv("DATABASE_URL"));
String username = dbUri.getUserInfo().split(":")[0];
String password = dbUri.getUserInfo().split(":")[1];
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + dbUri.getPath() + "?sslmode=require";
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setUrl(dbUrl);
basicDataSource.setUsername(username);
basicDataSource.setPassword(password);
return basicDataSource;
}
}
Heroku Postgres アドオンの DATABASE_URL
はこの命名規則に従います。
postgres://<username>:<password>@<host>/<dbname>
ただし、Postgres JDBC ドライバーは次の規則を使用します。
jdbc:postgresql://<host>:<port>/<dbname>?sslmode=require&user=<username>&password=<password>
jdbc:postgresql
の最後に ql
が追加されていることに注意してください。この違いのため、Java クラスまたは Spring XML 設定の jdbc:postgresql
にスキーマをハードコーディングする必要があります。
リモート接続
メンテナンスおよびデバッグの目的で、Heroku Postgres データベースにリモートで接続できます。ただし、そうするには、SSL 接続を使用する必要があります。JDBC 接続の URL は、次の URL パラメータを含む必要があります。
sslmode=require
sslmode=require
を中止すると、接続エラーが発生します。
注意: 環境設定を直接編集するのではなく、コードにこのパラメータを追加することが重要です。フェイルオーバーなどの自動化されたさまざまなイベントにより、環境設定が変更されることがあり、そこでの編集は失われます。
詳細については、ここをクリックし、「Java を使用して Heroku でリレーショナルデータベースに接続する」に関する Dev Center の記事を参照してください。
Ruby での接続
Ruby アプリケーションで PostgreSQL をデータベースとして使用するには、Gemfile
に pg
gem を含める必要があります。
gem 'pg'
bundle install
を実行して、すべての依存関係をダウンロードして解決します。
pg
gem を使用して、Heroku dyno から Postgres データベースに接続し、設定またはコードで sslmode
を指定していない場合、gem はデフォルトで sslmode: prefer
に設定されます。これは、Postgres データベースで SSL の使用が強制されている場合に、ご使用の接続が機能することを意味します。
Rails での接続
Rails アプリケーションが Heroku にデプロイされると、database.yml
ファイルがアプリケーション用に自動的に生成されます。これは、PostgreSQL 接続を使用し、DATABASE_URL
の場所にあるデータベースに接続するように、ActiveRecord を設定します。この動作は、Rails 4.1 までにのみ必要です。それ以降のすべてのバージョンには、database.yml
での接続 URL および設定の指定の直接サポートが含まれるので、上書きする必要はありません。
Rails アプリで PostgreSQL をローカルから使用するには、database.yml
に次の設定を含める必要があります。
development:
adapter: postgresql
host: localhost
username: user
database: app-dev
JRuby での接続
JRuby アプリケーションで PostgreSQL をデータベースとして使用するには、Gemfile
に activerecord-jdbcpostgresql-adapter
gem を含める必要があります。
gem 'activerecord-jdbcpostgresql-adapter'
bundle install
を実行して、すべての依存関係をダウンロードして解決します。
Rails を使用する場合、「Connecting with Rails」(Rails を使用した接続) の手順に従います。
Python での接続
Python アプリケーションで PostgreSQL をデータベースとして使用するには、psycopg2
パッケージを使用する必要があります。
$ pip install psycopg2-binary
また、コードでこのパッケージを使用して DATABASE_URL
に接続します。
import os
import psycopg2
DATABASE_URL = os.environ['DATABASE_URL']
conn = psycopg2.connect(DATABASE_URL, sslmode='require')
Django を使用した接続
pip
を使用して dj-database-url
パッケージをインストールします。
$ pip install dj-database-url
必ず、psycopg2-binary
および dj-database-url
を requirements.txt
ファイルにも追加してください。
続いて次のコマンドを settings.py
の下部に追加します。
import dj_database_url
DATABASES['default'] = dj_database_url.config(conn_max_age=600, ssl_require=True)
これは、DATABASE_URL
環境変数の値を解析し、Django が理解できるものにそれらを変換します。
Go での接続
pq を指定することにより、Go アプリを Heroku-Postgres に接続できます。 選択したクエリインターフェース (標準のデータベース/SQL) など) への Postgres データベースドライバー。 アプリは、ドライバーを直接使用するのではなく、クエリインターフェースを使用します。
標準の使用 (データベース/SQL)
$ cd <app>
$ dep ensure -add github.com/lib/pq
import (
"database/sql"
_ "github.com/lib/pq"
)
...
func main() {
db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
...
}
SSL は、Heroku-Postgres に接続するために必要です。 pq は自動的に sslmode=require を設定します。 ただし、別のライブラリを使用する場合、明示的に SSL を設定する必要があります。
標準ライブラリ以外
Postgres へのより下位のアクセスには、pgx を使用できます。
データベース/SQL の時間節約の拡張機能の場合、sqlx を使用できます。
PHP での接続
一般的な考慮事項
フレームワークまたはライブラリがデータベース URL をネイティブに処理できず、代わりにユーザー、パス、ホスト、ポート、データベース名などに個別の引数が必要になる場合は、DATABASE_URL
環境変数を解析し、抽出された詳細を使用して接続を確立するために、parse_url()
関数を使用できます。
データベース名を含むので、先頭のスラッシュはパスコンポーネントからトリミングされる必要があります。
$db = parse_url(getenv("DATABASE_URL"));
$db["path"] = ltrim($db["path"], "/");
結果の連想配列には、文書化されているように、「path
」キーから使用できるデータベース名を持つ URL からの情報が含まれます。
PQSQL 拡張機能を使用した接続
PQSQL 拡張機能は、URL スタイルの接続文字列をサポートする、基盤の libpq
ライブラリに接続文字列を直接渡します。したがって、DATABASE_URL
環境変数を直接使用できます。
$conn = pg_connect(getenv("DATABASE_URL"));
PDO を使用した接続
DSN は、PDO を使用して接続するように構成する必要があります。
$db = parse_url(getenv("DATABASE_URL"));
$pdo = new PDO("pgsql:" . sprintf(
"host=%s;port=%s;user=%s;password=%s;dbname=%s",
$db["host"],
$db["port"],
$db["user"],
$db["pass"],
ltrim($db["path"], "/")
));
Laravel を使用した接続
config/database.php
ファイルは、データベース接続情報の配列をフレームワークに返します。これは単純に、最初に DATABASE_URL
環境変数で parse_url()
を呼び出し、抽出されたデータを返すように修正できます。
$DATABASE_URL = parse_url(getenv("DATABASE_URL"));
return [
// …
'connections' => [
// …
'pgsql' => [
'driver' => 'pgsql',
'host' => $DATABASE_URL["host"],
'port' => $DATABASE_URL["port"],
'database' => ltrim($DATABASE_URL["path"], "/"),
'username' => $DATABASE_URL["user"],
'password' => $DATABASE_URL["pass"],
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'require',
],
// …
],
// …
];
Symfony 3 を使用した接続
DATABASE_URL
環境変数は、config.yml
で参照できます。Symfony の DoctrineBundle はその後、URL の内容を自動的に解析します。
Symfony 4 を使用した接続
Symfony 4 は、追加設定せずに、DATABASE_URL
環境変数を自動的に選択します。
Node.js での接続
依存関係として pg
NPM モジュールをインストールします。
$ npm install pg
続いて、アプリが初期化するときに、process.env.DATABASE_URL
に接続します。
const { Client } = require('pg');
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: true,
});
client.connect();
client.query('SELECT table_schema,table_name FROM information_schema.tables;', (err, res) => {
if (err) throw err;
for (let row of res.rows) {
console.log(JSON.stringify(row));
}
client.end();
});
注意: SSL 接続は、Heroku Postgres を接続するために必要です。
接続権限
Heroku Postgres ユーザーは、データベースのスーパーユーザー以外のすべての権限が認められています。これらには、SELECT
、INSERT
、UPDATE
、DELETE
、TRUNCATE
、REFERENCES
、TRIGGER
、CREATE
、CONNECT
、TEMPORARY
、EXECUTE
、および USAGE
と、制限された ALTER
および GRANT
の権限があります。
Heroku は、以下の SQL を実行して、ユーザーおよびデータベースを作成します。
CREATE ROLE user_name;
ALTER ROLE user_name WITH LOGIN PASSWORD 'password' NOSUPERUSER NOCREATEDB NOCREATEROLE;
CREATE DATABASE database_name OWNER user_name;
REVOKE ALL ON DATABASE database_name FROM PUBLIC;
GRANT CONNECT ON DATABASE database_name TO user_name;
GRANT ALL ON DATABASE database_name TO user_name;
複数のスキーマ
Heroku Postgres は、複数のスキーマをサポートし、作成できるスキーマの数を制限しません。
データベースで複数のスキーマを使用する最も一般的なユースケースは、お客様ごとに独自のスキーマが用意されている Software as a Service アプリケーションを構築することです。このテクニックは魅力的に見えますが、操作上に問題のある多数の事例を引き起こしているので決してお勧めしません。たとえば、適度な数のスキーマ (>50) でも、Heroku のデータベーススナップショットツールである PG バックアップのパフォーマンスに大きな影響を与えることがあります。
外部接続 (ingress)
Heroku ランタイムに使用できることに加え、Heroku Postgres データベースは、ローカルコンピューターや他の箇所で実行しているクライアントから直接アクセスできます。
すべての接続は SSL を必要とします: sslmode=require
。
2 つの方法のいずれかで、PG 接続文字列を取得できます。heroku pg:credentials
は上記で説明しています。
$ heroku pg:credentials DATABASE
Connection info string:
"dbname=dee932clc3mg8h host=ec2-123-73-145-214.compute-1.amazonaws.com port=6212 user=user3121 password=98kd8a9 sslmode=require"
また、接続文字列はアプリの環境設定として公開されます。
$ heroku config | grep HEROKU_POSTGRESQL
HEROKU_POSTGRESQL_YELLOW_URL: postgres://user3123:passkja83kd8@ec2-117-21-174-214.compute-1.amazonaws.com:6212/db982398
プラン間の移行
データベースプラン間の更新および移行に関するこの詳細なガイドを参照してください。
データの所在
データベースがプロビジョニングされると、そのデータベースに関連付けられたデータは、それが作成されるリージョン内で保管されます。ただし、データベース群を管理するシステムだけでなく Heroku Postgres に付随する多数のサービスは、プロビジョニングされたデータベースと同じリージョン内に配置することはできません。たとえば次のとおりです。
- ディザスタリカバリーの Postgres Continuous Protection は、データベースが置かれている同じリージョンにベースバックアップおよびログ先行書き込みを保管します。
- アプリケーションログは、Logplex にルーティングされ、米国でホスティングされます。アプリケーションのログに加え、これには、アプリケーションにアタッチされた任意のデータベースのシステムログと Heroku Postgres ログが含まれます。
- Heroku Postgres クエリおよびエラーのログ記録は、
heroku addons:create heroku-postgres:...
でデータベースを作成するときに --block-logs
フラグを使用することによってブロックできます。 - PG バックアップスナップショットは米国で保管されます。
- データクリップは米国で保管されます。
ログのブロック
アドオン作成時に、データベースに対して実行されるクエリのログ記録を防止するためにフラグを渡すことができます。このオプションをオンにした場合、データベースのプロビジョニングの終了後にオフにすることはできません。オンにした後にオフにする必要がある場合、新しいデータベースへの移行が必要になります。
この場合、ログでのクエリがブロックされるので、アプリケーションのデバッグに役立つ Heroku の能力やアプリケーションパフォーマンスが低下します。
$ heroku addons:create heroku-postgresql:standard-0 -a sushi --block-logs
アドオンの削除
Heroku Postgres データベースを破棄するには、アドオンを削除する必要があります。
$ heroku addons:destroy heroku-postgresql:hobby-dev
同じタイプの 2 つのデータベースがある場合、その環境設定名を使用してアドオンを削除する必要があります。たとえば、HEROKU_POSTGRESQL_GRAY_URL
を削除するには、次のように実行します。
heroku addons:destroy HEROKU_POSTGRESQL_GRAY
削除されたデータベースが DATABASE_URL
で使用されているものと同じであった場合、その DATABASE_URL
環境設定もアプリで未設定になります。
データベースは、破棄された後に再設定することはできません。PG バックアップを使用するか、データをエクスポートすることにより、あらかじめデータのスナップショットを撮ってください。
標準ツール
サポート
すべての Heroku Postgres サポートおよびランタイムの問題は、Heroku サポートチャネルのいずれかを介して送信する必要があります。