Ich muss eine Datenbank aus einem PostgreSQL-DB-Cluster entfernen. Wie kann ich das tun, auch wenn aktive Verbindungen bestehen? Ich brauche eine Art -forceFlag, das alle Verbindungen und dann die DB aufhebt.
Wie kann ich das umsetzen?
Ich benutze dropdbderzeit, aber andere Tools sind möglich.
In PostgreSQL * können Sie eine Datenbank nicht löschen, während Clients mit ihr verbunden sind.
Zumindest nicht mit dem dropdbDienstprogramm - das nur ein einfacher Wrapper für DROP DATABASEServerabfragen ist.
Es folgt eine recht robuste Problemumgehung:
Stellen Sie über oder einen anderen Client eine Verbindung zu Ihrem Server als Superuser herpsql . Verwenden Sie nicht die Datenbank, die Sie löschen möchten.
psql -h localhost postgres postgres
Mit dem normalen Datenbank-Client können Sie jetzt das Löschen der Datenbank in drei einfachen Schritten erzwingen:
Stellen Sie sicher, dass niemand eine Verbindung zu dieser Datenbank herstellen kann. Sie können eine der folgenden Methoden verwenden (die zweite scheint sicherer zu sein, verhindert jedoch nicht die Verbindungen von Superusern).
/* Method 1: update system catalog */UPDATE pg_database SET datallowconn ='false'WHERE datname ='mydb';/* Method 2: use ALTER DATABASE. Superusers still can connect!
ALTER DATABASE mydb CONNECTION LIMIT 0; */
Erzwingen Sie die Trennung aller mit dieser Datenbank verbundenen Clients mit pg_terminate_backend.
SELECT pg_terminate_backend(pid)FROM pg_stat_activityWHERE datname ='mydb';/* For old versions of PostgreSQL (up to 9.1), change pid to procpid:
SELECT pg_terminate_backend(procpid)
FROM pg_stat_activity
WHERE datname = 'mydb'; */
Löschen Sie die Datenbank.
DROPDATABASE mydb;
Für Schritt 1 sind Superuser- Berechtigungen für die erste Methode und Datenbankbesitzer- Berechtigungen für die zweite Methode erforderlich . Schritt 2 erfordert Superuser- Berechtigungen. Schritt 3 erfordert die Berechtigung des Datenbankbesitzers .
* Dies gilt für alle Versionen von PostgreSQL bis zur Version 11.
Ich weiß also nicht, was ich falsch gemacht habe, aber jetzt kann ich nicht einmal eine Verbindung zu der Datenbank herstellen, auf die ich abzielte! Ich kann es auch nicht
löschen,
@MattSkeldon, keine Ahnung, was diese Nachricht bedeutet. In Vanille PostgreSQL können Sie jede Datenbank außer template0 und template1 löschen. Vielleicht verwenden Sie eine unfreie / kommerzielle Version? Vielleicht ist es Client-Problem nicht Server-Problem? Hast du psql ausprobiert?
Filiprem
Leider komme ich aus einem SQL-Hintergrund, mit PGSQL wird aufgrund des nicht kommerziellen / kostenlosen Status gearbeitet.
Matt Skeldon
Bei Zombiesitzungen mit langer Laufzeit funktioniert das nicht. pg_terminate_backend () bricht diese Sitzungen nicht ab, daher bin ich immer noch ein bisschen festgefahren: Ich bin ein Postgres-Mitglied, aber ich habe keinen Zugriff auf den Server, auf dem es ausgeführt wird.
Alexander
6
Es gibt eine Möglichkeit, dies mit den Shell-Dienstprogrammen dropdb& pg_ctl(oder pg_ctlclusterin Debian und Derivaten) zu tun . Aber Methode des @ filiprem überlegen ist aus mehreren Gründen:
Es werden nur Benutzer von der betreffenden Datenbank getrennt.
Es muss nicht der gesamte Cluster neu gestartet werden.
Es verhindert das sofortige Wiederherstellen der Verbindung und beeinträchtigt möglicherweise den dropdbBefehl.
Ich zitiere man pg_ctlcluster:
Mit der --forceOption "schnell" werden alle aktiven Transaktionen zurückgesetzt, Clients sofort getrennt und somit sauber heruntergefahren. Wenn dies nicht funktioniert, wird im Sofortmodus erneut versucht, den Cluster herunterzufahren. Dies kann zu einem inkonsistenten Zustand des Clusters führen und führt beim nächsten Start zu einem Wiederherstellungslauf. Wenn dies immer noch nicht hilft, wird der Postmaster-Prozess abgebrochen. Beendet den Vorgang mit 0 bei Erfolg, mit 2, wenn der Server nicht ausgeführt wird, und mit 1 bei anderen Fehlerbedingungen. Dieser Modus sollte nur verwendet werden, wenn die Maschine heruntergefahren werden soll.
pg_ctlcluster 9.1 main restart --force
oder
pg_ctl restart -D datadir -m fast
oder
pg_ctl restart -D datadir -m immediate
unmittelbar gefolgt von:
dropdb mydb
Möglicherweise in einem Skript zur sofortigen Nachfolge.
Dies ist nicht nur weniger als ideal, da es die gesamte Postgres-Instanz auslöst, sondern es ist auch nicht garantiert, dass es funktioniert. Ein Client kann zwischen dem Neustart des Servers und dem erneuten Versuch, dropdb auszuführen, eine Verbindung herstellen. Durch die obige Antwort von @filiprem werden alle Verbindungen zur Datenbank vor dem Trennen der Verbindung deaktiviert, und andere Datenbanken bleiben erhalten.
Jim Mitchener
6
Verwendung der Antwort von @ filiprem in einem meiner Fälle und Vereinfachung:
-- Connecting to the current user localhost's postgres instance
psql
-- Making sure the database existsSELECT*from pg_database where datname ='my_database_name'-- Disallow new connectionsUPDATE pg_database SET datallowconn ='false'WHERE datname ='my_database_name';ALTERDATABASE my_database_name CONNECTION LIMIT 1;-- Terminate existing connectionsSELECT pg_terminate_backend(pid)FROM pg_stat_activity WHERE datname ='my_database_name';-- Drop databaseDROPDATABASE my_database_name
Wenn Sie sich in einer RDS-Umgebung befinden, in der Verbindungen ohne ausgewählte Datenbank Sie in die Datenbank versetzen, für die Sie standardmäßig die Erstellung beantragt haben, können Sie diese Variante ausführen, um sich selbst als letzte offene Verbindung zu umgehen.
Es gibt eine Möglichkeit, dies mit den Shell-Dienstprogrammen
dropdb
&pg_ctl
(oderpg_ctlcluster
in Debian und Derivaten) zu tun . Aber Methode des @ filiprem überlegen ist aus mehreren Gründen:dropdb
Befehl.Ich zitiere
man pg_ctlcluster
:oder
oder
unmittelbar gefolgt von:
Möglicherweise in einem Skript zur sofortigen Nachfolge.
quelle
Verwendung der Antwort von @ filiprem in einem meiner Fälle und Vereinfachung:
quelle
Wenn Sie sich in einer RDS-Umgebung befinden, in der Verbindungen ohne ausgewählte Datenbank Sie in die Datenbank versetzen, für die Sie standardmäßig die Erstellung beantragt haben, können Sie diese Variante ausführen, um sich selbst als letzte offene Verbindung zu umgehen.
quelle