Wie trenne ich alle anderen Benutzer von einer Postgres-Datenbank?

13

Ich benötige exklusiven Zugriff auf eine Datenbank. Ist es möglich, mit einem SQL-Befehl alle anderen Benutzer von einer Postgres-Datenbank zu trennen? Oder schließen Sie alle anderen Verbindungen und erhalten Sie exklusiven Zugriff.

Dies dient zum Testen von Einheiten und die Tests werden nur manuell ausgeführt, sodass keine Gefahr besteht. Es sind nur alte tote Verbindungen betroffen.

Es gibt keine anderen Benutzer, die eine Verbindung zu diesen unittesten Datenbanken herstellen.

Die alten toten Verbindungen entstehen durch die Entwicklung. Dies passiert die ganze Zeit, wenn ein Test, der gerade geschrieben wird oder fehlschlägt, nicht sauber beendet wird.


Wenn jemand andere Benutzer nach dem Trennen der Verbindung in einem Produktionsszenario für eine Weile aussperren muss, lesen Sie die nachstehende Antwort von Scott Marlowe: /dba//a/6184/2024


Siehe auch diese ähnliche Frage zu dba: Wie löse ich alle Verbindungen zu einer bestimmten Datenbank, ohne den Server zu stoppen?

mit
quelle

Antworten:

14

Sie können versuchen, als postgres-Benutzer eine Verbindung zur Datenbank herzustellen und Folgendes auszuführen:

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( )
    );

update Eine noch bessere Abfrage beseitigt die Unterauswahl:

SELECT pg_terminate_backend( procpid )
FROM pg_stat_activity
WHERE procpid <> pg_backend_pid( )
    AND datname = current_database( );
gsiems
quelle
2
Vergessen Sie nicht, die CONNECT-Berechtigungen zu widerrufen. Andernfalls erstellen die Benutzer neue Verbindungen, bevor Sie exklusiven Zugriff haben.
Frank Heikens
@ Frank Heikens - Guter Fang. Ich hatte "manueller Komponententest" aktiviert, aber wenn neben der Person, die den Komponententest durchführt, noch andere Personen eine Verbindung herstellen, ist "Verbindung auf <Datenname> aufheben von ..." unerlässlich.
gsiems
Wurde in PostgreSQL 9.2 procpidin umbenannt pid, achten Sie darauf.
Craig Ringer
Abgesehen davon, dass ich mit dem fraglichen Benutzer eine REVOKE-Aktion durchgeführt habe, musste ich auch REVOKE ..... public ausführen - etwas, auf das ich achten muss!
David N. Welton
In Version 9.3 heißt pg_stat_activity.procpid jetzt pg_stat_activity.pid . ansonsten hat a-ok geklappt.
JL Peyret
4

Es gibt zwei Probleme: Zum einen müssen Sie diese Benutzer trennen und zum anderen müssen Sie sie von Ihrem Server fernhalten. Anstatt die Verbindungserlaubnis zu widerrufen, verwende ich normalerweise pg_hba.conf, um neue Verbindungen von bestimmten Rechnern und / oder Benutzern abzulehnen. Dann mache ich einfach einen Schnellstopp mit pg_ctl -m; pg_ctl start, um alle aktuellen Verbindungen zu löschen. Wenn Slony DDL-Änderungen vornimmt, ist dies so ziemlich eine Notwendigkeit, sonst kommt es überall zu Deadlocks.

Scott Marlowe
quelle
5
Ich benutze immer eine einzelne Rolle, die CONNECT erlaubt und von allen anderen Rollen geerbt wird. REVOKE connect für diese einzelne Rolle und fertig. Schließen Sie es mit pg_terminate_backend () in eine Funktion ein, und Sie haben die Kontrolle, wenn Sie alle aktuellen Verbindungen beenden müssen.
Frank Heikens