web-dev-qa-db-ja.com

サーバーを停止せずに特定のデータベースへのすべての接続をドロップする方法は?

特定のPostgreSQLデータベースに対して現在開かれているが、サーバーを再起動したり、他のデータベースへの接続を切断したりせずに、すべての接続(セッション)をドロップしたい。

どうやってやるの?

60
sorin

StackOverflowの 非常によく似た質問 に対する私の答えは次のとおりです。

Postgresqlのバージョンによっては、pg_stat_activityドロップされたユーザーからのアクティブな接続を省略します。これらの接続は、pgAdminIII内にも表示されません。

(ユーザーも作成する)自動テストを実行している場合、これはおそらくシナリオです。

この場合、次のようなクエリに戻す必要があります。

 SELECT pg_terminate_backend(pg_stat_activity.procpid) 
 FROM pg_stat_get_activity(NULL::integer) 
 WHERE datid=(SELECT oid from pg_database where datname = 'your_database');
27
jb.

このようなクエリは役立つはずです(データベースの名前が 'db'であると想定しています)。

select pg_terminate_backend(pid) from pg_stat_activity where datname='db';

pidは以前はprocpidと呼ばれていたため、9.2より前のバージョンのpostgresを使用している場合は、次のことを試すことができます。

select pg_terminate_backend(procpid) from pg_stat_activity where datname='db';

ただし、他のユーザーを切断するには、スーパーユーザーである必要があります。

また、REVOKE CONNECT ON DATABASE FROM PUBLICまたは類似のものを使用し、その後GRANTを使用すると便利な場合があります。

101
Szymon Guz

これは、クライアント接続からデータベースを「解放」するために使用できるため、たとえば、次のように名前を変更できます。

SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname='current_db';
ALTER DATABASE current_db RENAME TO old_db;
ALTER DATABASE new_db RENAME TO current_db;

これにより、クライアントアプリに問題のある動作が発生する可能性があることに注意してください。トランザクションを使用するために、データが実際に破損することはありません。

3
cysk