CLI を使用した Heroku Postgres の管理
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2023年05月17日(水)
Table of Contents
Heroku Postgres は、Heroku CLI に直接統合され、一般的なデータベースタスクを簡略化する多くの役立つコマンドを提供します。
pg:info
アプリケーションによりプロビジョニングされるすべての PostgreSQL データベースと、それぞれの識別特性 (データベースサイズ、ステータス、テーブル数、PG バージョンなど) を確認するには、heroku pg:info
コマンドを使用します。
$ heroku pg:info -a example-app
=== HEROKU_POSTGRESQL_RED
Plan Standard 0
Status available
Data Size 82.8 GB
Tables 13
PG Version 12.5
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 -a example-app
pg:psql
psql
は、ネイティブの PostgreSQL 対話型ターミナルであり、クエリを実行し、接続されたデータベースにコマンドを発行するために使用されます。
リモートデータベースとの psql
セッションを確立するには、heroku pg:psql
を使用します。
heroku pg:psql
を使用するには、PostgreSQL がシステムにインストールされている必要があります。
$ heroku pg:psql
Connecting to HEROKU_POSTGRESQL_RED... done
psql (12.5, server 12.5)
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 DATABASE_URL mylocaldb --app example-app
このコマンドは、mylocaldb
という新しいローカルデータベースを作成し、続いてアプリ example-app
から、DATABASE_URL
にあるデータベースのデータをプルします。データをそこからプルする必要があるデータベースアドオンの名前を指定することもできます。
$ heroku pg:pull postgresql-animate-91581 mylocaldb --app example-app
データが誤って上書きされたり、失われたりしないように、ローカルデータベースはまだ存在してはなりません。先に進む前に、既存のローカルデータベースを削除するよう求められます。
ローカル DB に Postgres ユーザーまたはパスワードを提供する必要がある場合は、次のような適切な環境変数を使用します。
$ PGUSER=postgres PGPASSWORD=password heroku pg:pull DATABASE_URL mylocaldb --app example-app
すべての pg:*
コマンドと同様に、ここでは省略表現のデータベース識別子を使用できます。たとえば、アプリ example-app
上の HEROKU_POSTGRESQL_RED
からデータをプルするには、heroku pg:pull example-app::RED mylocaldb
を実行できます。
pg:push
pg:push
は、リモート Heroku Postgres データベースにローカルデータベースからのデータをプッシュします。コマンドは次のようになります。
$ heroku pg:push mylocaldb DATABASE_URL --app example-app
このコマンドは、ローカルデータベース mylocaldb
を選んで、アプリ example-app
の DATABASE_URL
にあるデータベースにプッシュします。データをそこにプッシュする必要があるデータベースアドオンの名前を指定することもできます。
$ heroku pg:push postgresql-animate-91581 mylocaldb --app example-app
誤ってデータが上書きされたり失われることがないように、リモートデータベースは空である必要があります。空でないリモートデータベースに対して pg:reset
を実行するよう求められます。
ローカルデータベースに対する PGUSER
および PGPASSWORD
の使用は、pg:pull
コマンドの場合と同様に、pg:push
でもサポートされています。
$ PGUSER=postgres PGPASSWORD=password heroku pg:push DATABASE_URL mylocaldb --app example-app
トラブルシューティング
これらのコマンドは、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: 12.5; pg_dump version: 10.14
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 列を使用できます。引数を使用しない場合は、pg_cancel_backend がクエリで呼び出され、そのクエリをキャンセルしようとします。それが失敗した場合は、--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
コマンドを使用して、データベースをアプリのプライマリにプロモートします。
pg:promote
では、DATABASE_URL
環境設定の値が、新しくプロモートされたデータベースの接続文字列に更新されます。また、新しい HEROKU_POSTGRESQL_<color>_URL
環境設定に割り当てられた、古いプライマリデータベースの代替アタッチメントも作成されます。このプロモーションプロセスによってリリースがトリガーされ、アプリが再起動されます。
$ heroku pg:promote HEROKU_POSTGRESQL_GRAY_URL -a example-app
Ensuring an alternate alias for existing DATABASE_URL... HEROKU_POSTGRESQL_PINK_URL
Promoting HEROKU_POSTGRESQL_GRAY_URL to DATABASE_URL... done
フォロワーデータベースに対して pg:promote
を実行しても、それが自動的にそのリーダーをフォロー解除するようにはなりません。プロモートする前に複製を停止するには、フォロワーに対して pg:unfollow
を実行してください
プロモーションの後も、デモートされたデータベースは引き続き存在し、料金が発生します。heroku addons:destroy HEROKU_POSTGRESQL_COLOR
を使用して、古いプライマリデータベースを削除してください。
接続プールを使用しているときのプロモーション
古いプライマリで、デフォルト名 DATABASE_CONNECTION_POOL
でアタッチされた接続プールを使用していた場合、pg:promote
は、接続プーラーを新しいプライマリに再アタッチします。
接続プールアタッチメントをデフォルト以外の名前で使用している場合は、pg:promote
を実行した後、それを更新する必要があります。接続プールの URL を再び指すには、新しいプライマリで接続プールをアクティブにします。
$ heroku pg:connection-pooling:attach DATABASE_URL --as MY_DATABASE_CONNECTION_POOL -a example-app
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