Ich muss ein Skript schreiben, das eine PostgreSQL-Datenbank löscht. Möglicherweise gibt es viele Verbindungen, aber das Skript sollte dies ignorieren.
Die Standardabfrage DROP DATABASE db_name
funktioniert nicht, wenn offene Verbindungen bestehen.
Wie kann ich das Problem lösen?
postgresql
Roman Prykhodchenko
quelle
quelle
Antworten:
Dadurch werden vorhandene Verbindungen außer Ihren getrennt:
Abfrage
pg_stat_activity
und erhalten Sie die pid Werte , die Sie töten wollen, dann erteilenSELECT pg_terminate_backend(pid int)
ihnen.PostgreSQL 9.2 und höher:
PostgreSQL 9.1 und niedriger:
Sobald Sie alle getrennt haben, müssen Sie den Befehl DROP DATABASE von einer Verbindung aus einer anderen Datenbank trennen und ausgeben, auch bekannt als nicht die, die Sie löschen möchten.
Beachten Sie die Umbenennung der
procpid
Spalte inpid
. Siehe diesen Mailinglisten-Thread .quelle
; drop database TARGET_DB;
in meinem Fall gut funktioniert , dies kurz zuvor zu tun, um sicherzustellen, dass die Datenbank zu dem Zeitpunkt, als die Dinge erneut versucht wurden, verschwunden war.dropdb --force
.In PostgreSQL 9.2 und höher können Sie alle Verbindungen außer Ihrer Sitzung von der Datenbank trennen, mit der Sie verbunden sind:
In älteren Versionen ist es dasselbe, wechseln Sie einfach
pid
zuprocpid
. Um die Verbindung zu einer anderen Datenbank zu trennen, änderncurrent_database()
Sie einfach den Namen der Datenbank, von der Sie die Verbindung trennen möchten.Möglicherweise möchten Sie sich von
REVOKE
denCONNECT
Benutzern der Datenbank abheben, bevor Sie die Verbindung zu den Benutzern trennen. Andernfalls stellen die Benutzer die Verbindung einfach wieder her und Sie haben nie die Möglichkeit, die Datenbank zu löschen. Sehen Sie diesen Kommentar und die Frage dem er zugeordnet ist, Wie kann ich lösen alle anderen Benutzer aus der Datenbank .Wenn Sie nur inaktive Benutzer trennen möchten, lesen Sie diese Frage .
quelle
Sie können alle Verbindungen beenden, bevor Sie die Datenbank mit der
pg_terminate_backend(int)
Funktion löschen.Sie können alle laufenden Backends über die Systemansicht abrufen
pg_stat_activity
Ich bin nicht ganz sicher, aber das Folgende würde wahrscheinlich alle Sitzungen beenden:
Natürlich sind Sie möglicherweise nicht selbst mit dieser Datenbank verbunden
quelle
Abhängig von Ihrer Version von postgresql kann es zu einem Fehler kommen, der
pg_stat_activity
dazu führt , dass aktive Verbindungen von abgelegten Benutzern weggelassen werden. Diese Verbindungen werden auch in pgAdminIII nicht angezeigt.Wenn Sie automatische Tests durchführen (in denen Sie auch Benutzer erstellen), ist dies möglicherweise ein wahrscheinliches Szenario.
In diesem Fall müssen Sie zu folgenden Abfragen zurückkehren:
HINWEIS: In 9.2+ Sie ändern müssen
procpid
zupid
.quelle
procpid
zupid
diesem Snippet funktioniert 9.3.Mir ist aufgefallen, dass Postgres 9.2 jetzt eher die Spalten-PID als die Procpid aufruft.
Ich neige dazu, es aus der Shell zu nennen:
Hoffe das ist hilfreich. Danke an @JustBob für die SQL.
quelle
Ich starte den Dienst in Ubuntu einfach neu, um verbundene Clients zu trennen.
quelle
In der Linux-Eingabeaufforderung würde ich zuerst alle ausgeführten postgresql-Prozesse stoppen, indem ich diesen Befehl verknüpfe sudo /etc/init.d/postgresql restart verknüpfe
Geben Sie den Befehl bg einGeben Sie , um zu überprüfen, ob noch andere postgresql-Prozesse ausgeführt werden
dann gefolgt von dropdb dbname , um die Datenbank zu löschen
Dies funktioniert bei mir an der Linux-Eingabeaufforderung
quelle
PostgreSQL 9.2 und höher:
SELECT pg_terminate_backend(pid)FROM pg_stat_activity WHERE datname = 'YOUR_DATABASE_NAME_HERE'
quelle
Hier ist mein Hack ... = D.
Ich habe diese Antwort gegeben, weil ich einen Befehl (oben) zum Blockieren neuer Verbindungen eingefügt habe und weil jeder Versuch mit dem Befehl ...
... funktioniert nicht, um neue Verbindungen zu blockieren!
Vielen Dank an @araqnid @GoatWalker! = D.
https://stackoverflow.com/a/3185413/3223785
quelle
Das kommende PostgreSQL 13 wird die
FORCE
Option einführen .quelle
In meinem Fall musste ich einen Befehl ausführen, um alle Verbindungen einschließlich meiner aktiven Administratorverbindung zu trennen
Das hat alle Verbindungen beendet und mir eine schwerwiegende Fehlermeldung angezeigt:
FATAL: terminating connection due to administrator command SQL state: 57P01
Danach war es möglich, die Datenbank zu löschen
quelle
Bei mir hat nichts funktioniert, außer ich habe mich mit pgAdmin4 angemeldet und im Dashboard alle Verbindungen außer pgAdmin4 getrennt und konnte dann durch Klicken mit der rechten Maustaste auf die Datenbank und die Eigenschaften umbenennen und einen neuen Namen eingeben.
quelle