PostgreSQL DBクラスターからデータベースを削除する必要があります。アクティブな接続がある場合でもどうすればよいですか? -force
フラグが必要です。これにより、すべての接続がドロップされ、次にDBがドロップされます。
どうすれば実装できますか?
現在dropdb
を使用していますが、他のツールも使用できます。
PostgreSQL内*、クライアントが接続している間はデータベースを削除できません。
少なくとも、 dropdb
ユーティリティでは使用できません。これは DROP DATABASE
サーバークエリの単なるラッパーです。
かなり堅牢な回避策は次のとおりです。
psql
または他のクライアントを使用して、superuserとしてサーバーに接続します。削除するデータベースを使用するしない。
psql -h localhost postgres postgres
プレーンデータベースクライアントを使用すると、3つの簡単な手順でデータベースを強制的に削除できます。
誰もこのデータベースに接続できないことを確認してください。次のいずれかの方法を使用できます(2番目の方法はより安全に見えますが、スーパーユーザーからの接続を妨げません)。
/* Method 1: update system catalog */
UPDATE pg_database SET datallowconn = 'false' WHERE datname = 'mydb';
/* Method 2: use ALTER DATABASE. Superusers still can connect!
ALTER DATABASE mydb CONNECTION LIMIT 0; */
pg_terminate_backend
を使用して、このデータベースに接続されているすべてのクライアントを強制的に切断します。
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'mydb';
/* For old versions of PostgreSQL (up to 9.1), change pid to procpid:
SELECT pg_terminate_backend(procpid)
FROM pg_stat_activity
WHERE datname = 'mydb'; */
データベースを削除します。
DROP DATABASE mydb;
ステップ1には、1番目のメソッドのsuperuser特権、およびデータベース所有者特権が必要です2つ目のために。ステップ2にはsuperuser特権が必要です。ステップ3にはデータベース所有者特権が必要です。
* これは、バージョン12までのPostgreSQLのすべてのバージョンに適用されます。バージョン13にはDROP DATABASE mydb FORCE
があります。
私のケースで@filipremの答えを使用してそれを簡素化します:
-- Connecting to the current user localhost's postgres instance
psql
-- Making sure the database exists
SELECT * from pg_database where datname = 'my_database_name'
-- Disallow new connections
UPDATE pg_database SET datallowconn = 'false' WHERE datname = 'my_database_name';
ALTER DATABASE my_database_name CONNECTION LIMIT 1;
-- Terminate existing connections
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'my_database_name';
-- Drop database
DROP DATABASE my_database_name
シェルユーティリティdropdb
&pg_ctl
(またはDebianとその派生物ではpg_ctlcluster
)でこれを行う方法がです。しかし、@ filipremの方法 は、いくつかの理由で優れています。
dropdb
コマンドを無効にする可能性があります。引用するman pg_ctlcluster
:
--force
オプションを使用すると、すべてのアクティブなトランザクションをロールバックし、クライアントをすぐに切断して、完全にシャットダウンする「高速」モードが使用されます。それが機能しない場合は、「即時」モードでシャットダウンが再試行されます。これにより、クラスターが不整合な状態のままになり、次回の起動時にリカバリーが実行される可能性があります。それでも解決しない場合は、postmasterプロセスが強制終了されます。成功した場合は0で終了し、サーバーが実行されていない場合は2で終了し、その他の失敗の場合は1で終了します。このモードは、マシンがシャットダウンされる直前にのみ使用してください。
pg_ctlcluster 9.1 main restart --force
または
pg_ctl restart -D datadir -m fast
または
pg_ctl restart -D datadir -m immediate
直後に続く:
dropdb mydb
おそらく、すぐに引き継ぐために台本の中で.
データベースを選択せずに接続すると、デフォルトで作成するように要求されたDBに入るRDSのようなものを使用している場合、このバリアントを実行して、最後に開いている接続を回避できます。
DROP DATABASE IF EXISTS temporary_db_that_shouldnt_exist;
CREATE DATABASE temporary_db_that_shouldnt_exist with OWNER your_user;
\connect temporary_db_that_shouldnt_exist
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'the_db_you_want_removed';
DROP DATABASE IF EXISTS the_db_you_want_removed;
--
-- Name: the_db_you_want_removed; Type: DATABASE; Schema: -; Owner: your_user
--
CREATE DATABASE savings_champion WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8';
ALTER DATABASE the_db_you_want_removed OWNER TO your_user;
\connect the_db_you_want_removed
DROP DATABASE IF EXISTS temporary_db_that_shouldnt_exist;