PostgreSQLデータベースを削除するスクリプトを作成する必要があります。多くの接続があるかもしれませんが、スクリプトはそれを無視する必要があります。
DROP DATABASE db_name
開いている接続がある場合、標準クエリは機能しません。
どうすれば問題を解決できますか?
PostgreSQLデータベースを削除するスクリプトを作成する必要があります。多くの接続があるかもしれませんが、スクリプトはそれを無視する必要があります。
DROP DATABASE db_name
開いている接続がある場合、標準クエリは機能しません。
どうすれば問題を解決できますか?
回答:
これはあなたのものを除いて既存の接続を落とします:
pg_stat_activity
killするpid値をクエリして取得し、SELECT pg_terminate_backend(pid int)
それらに発行します。
PostgreSQL 9.2以降:
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB' -- ← change this to your DB
AND pid <> pg_backend_pid();
PostgreSQL 9.1以前:
SELECT pg_terminate_backend(pg_stat_activity.procpid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB' -- ← change this to your DB
AND procpid <> pg_backend_pid();
全員を切断したら、切断して、ドロップしようとしているデータベースではなく、別のデータベースからの接続からDROP DATABASEコマンドを発行する必要があります。
procpid
列の名前がに変更されていることに注意してくださいpid
。このメーリングリストのスレッドをご覧ください。
; drop database TARGET_DB;
うまくいき、再試行が始まるまでにdbがなくなったことを確認できます。
dropdb --force
。
PostgreSQL 9.2以降では、セッション以外のすべてを接続しているデータベースから切断するには:
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
AND pid <> pg_backend_pid();
古いバージョンでも同じですが、に変更pid
してくださいprocpid
。別のデータベースから切断するには、current_database()
ユーザーを切断するデータベースの名前に変更します。
あなたはしたいことがあり、ユーザーを切断する前に、データベースのユーザーから右のそれ以外のユーザーは、ちょうど再接続し続けますと、あなたはDBをドロップするチャンスを得ることは決してないだろう。このコメントとそれに関連する質問を参照してください。他のすべてのユーザーをデータベースから切り離すにはどうすればよいですか。REVOKE
CONNECT
アイドル状態のユーザーを切断したいだけの場合は、この質問を参照してください。
postgresqlのバージョンによっては、pg_stat_activity
ドロップされたユーザーからのアクティブな接続を除外するというバグに遭遇する可能性があります。これらの接続は、pgAdminIII内にも表示されません。
(ユーザーも作成する)自動テストを実行している場合、これはおそらくシナリオです。
この場合、次のようなクエリに戻す必要があります。
SELECT pg_terminate_backend(procpid)
FROM pg_stat_get_activity(NULL::integer)
WHERE datid=(SELECT oid from pg_database where datname = 'your_database');
注:9.2以降では、に変更さprocpid
れpid
ます。
procpid
するとpid
、9.3で動作します。
postgres 9.2がprocpidではなく列pidを呼び出すようになったことに気づきました。
私はそれをシェルから呼び出す傾向があります:
#!/usr/bin/env bash
# kill all connections to the postgres server
if [ -n "$1" ] ; then
where="where pg_stat_activity.datname = '$1'"
echo "killing all connections to database '$1'"
else
echo "killing all connections to database"
fi
cat <<-EOF | psql -U postgres -d postgres
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
${where}
EOF
お役に立てば幸いです。SQLの@JustBobに感謝します。
Linuxコマンドプロンプトでは、最初にこのコマンドsudo /etc/init.d/postgresql restartを実行して、実行中のすべてのpostgresqlプロセスを停止します。
コマンドbgを入力して、 他のpostgresqlプロセスがまだ実行されているかどうかを確認します
次にdropdb dbnameを実行してデータベースを削除します
sudo /etc/init.d/postgresql restart
bg
dropdb dbname
これはLinuxコマンドプロンプトで私のために動作します
これが私のハックです... = D
# Make sure no one can connect to this database except you!
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "UPDATE pg_database SET datallowconn=false WHERE datname='<DATABASE_NAME>';"
# Drop all existing connections except for yours!
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '<DATABASE_NAME>' AND pid <> pg_backend_pid();"
# Drop database! =D
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "DROP DATABASE <DATABASE_NAME>;"
新しい接続をブロックするコマンド(上記)を含めるため、およびコマンドでのすべての試行のため、この答えを出しました...
REVOKE CONNECT ON DATABASE <DATABASE_NAME> FROM PUBLIC, <USERS_ETC>;
...新しい接続をブロックするように機能しない!
@araqnid @GoatWalkerに感謝します!= D
次のPostgreSQL 13ではFORCE
オプションが導入されます。
DROP DATABASEはデータベースを削除します...また、他の誰かがターゲットデータベースに接続している場合、以下で説明するFORCEオプションを使用しない限り、このコマンドは失敗します。
力
ターゲットデータベースへの既存の接続をすべて終了してみます。準備されたトランザクション、アクティブな論理レプリケーションスロット、またはサブスクリプションがターゲットデータベースに存在する場合は、終了しません。
DROP DATABASE db_name WITH (FORCE);
私の場合、アクティブな管理者接続を含むすべての接続をドロップするコマンドを実行する必要がありました
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
すべての接続が終了し、致命的な「エラー」メッセージが表示されました:
FATAL: terminating connection due to administrator command SQL state: 57P01
その後、データベースを削除することができました