postgresデータベースから他のすべてのユーザーをデタッチするにはどうすればよいですか?


13

データベースへの排他的アクセスが必要です。SQLコマンドを使用して、postgresデータベースから他のすべてのユーザーを「切り離す」ことは可能ですか?または、他のすべての接続を閉じてから排他アクセスを取得することもできます。

これは単体テスト用であり、テストは手動でのみ実行されるため、危険はありません。古いデッド接続のみが影響を受けます。

これらの単体テストデータベースに接続している他のユーザーはいません。

古いデッド接続は開発から来ています。これは、書き込まれているテストまたは失敗したテストがクリーンに終了しない場合に常に発生します。


生産シナリオで他のユーザーを切断した後、他のユーザーをしばらくロックアウトしたままにする必要がある場合は、以下のScott Marloweの回答を参照してください。https//dba.stackexchange.com/a/6184/2024


dbaに関する同様の質問もご覧ください。サーバーを停止せずに特定のデータベースへのすべての接続をドロップする方法は?

回答:


14

postgresユーザーとしてデータベースに接続し、実行してみてください:

SELECT pg_terminate_backend( procpid )
FROM pg_stat_activity
WHERE procpid <> pg_backend_pid( )    -- 1. don't terminate your own session
    AND datname =                     -- 2. don't terminate connections to 
    (SELECT datname                   --    other databases in the cluster
       FROM pg_stat_activity
      WHERE procpid = pg_backend_pid( )
    );

更新 さらに良いクエリは副選択を取り除きます:

SELECT pg_terminate_backend( procpid )
FROM pg_stat_activity
WHERE procpid <> pg_backend_pid( )
    AND datname = current_database( );

2
CONNECTパーミッションを取り消すことを忘れないでください。そうしないと、排他的アクセス権を持つ前にユーザーが新しい接続を作成します。
フランクヘイケンス

@Frank Heikens-良いキャッチ。「手動ユニットテスト」をキーにしていましたが、ユニットテストを行う個人以外に接続している他の人がいる場合、「<datname>での接続を無効にする...」が不可欠です。
gsiems

PostgreSQL 9.2では、procpidに名前が変更されましたpidので、注意してください。
クレイグリンガー

問題のユーザーと一緒にREVOKEを行うだけでなく、..... publicを取り消す必要がありました。
デビッドN.ウェルトン14年

9.3上では、と思われpg_stat_activity.procpidが今と呼ばれるpg_stat_activity.pid。それ以外はA-OKで動作しました。
JLペイレット

4

ここでの問題は2つあります。1つ目はユーザーを切断する必要があり、2つ目はサーバーにアクセスしないようにする必要があることです。接続許可を取り消すのではなく、通常pg_hba.confを使用して特定のマシンやユーザーからの新しい接続を拒否し、pg_ctl -m fast stop; pg_ctl startを実行して現在のすべての接続をドロップします。slonyがDDLの変更を行う場合、これは非常に必要です。さもないと、あちこちでデッドロックが発生します。


5
私は常に、CONNECTを許可し、他のすべてのロールに継承される単一のロールを使用します。REVOKEがこの単一の役割に接続すると、完了です。pg_terminate_backend()で関数にラップすると、現在の接続をすべて停止する必要があるときに制御できます。
フランクヘイケンズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.