it-swarm.com.de

Postgresql - Datenbank kann aufgrund einiger automatischer Verbindungen zur Datenbank nicht gelöscht werden

Immer wenn ich versuche, die Datenbank zu löschen, bekomme ich:

ERROR:  database "pilot" is being accessed by other users
DETAIL:  There is 1 other session using the database.

Wenn ich benutze:

SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB';

Ich habe die Verbindung von dieser Datenbank abgebrochen, aber wenn ich versuche, die Datenbank danach zu löschen, stellt sich irgendwie automatisch eine Verbindung zu dieser Datenbank her und gibt diesen Fehler aus. Was könnte das tun? Niemand benutzt diese Datenbank außer mir.

91
Andrius

Sie können zukünftige Verbindungen verhindern:

REVOKE CONNECT ON DATABASE thedb FROM public;

(und möglicherweise andere Benutzer/Rollen; siehe \l+ in psql)

Sie können dann alle Verbindungen zu dieser Datenbank mit Ausnahme Ihrer eigenen trennen:

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

In älteren Versionen wurde pid als procpid bezeichnet, daher müssen Sie damit umgehen.

Da Sie CONNECT-Rechte widerrufen haben, sollte das, was versucht hat, eine automatische Verbindung herzustellen, dies nicht mehr tun können.

Sie können jetzt die Datenbank löschen.

Dies funktioniert nicht, wenn Sie Superuser-Verbindungen für den normalen Betrieb verwenden, aber wenn Sie dies tun, müssen Sie das Problem zuerst beheben.

98
Craig Ringer

Immer wenn ich versuche, die Datenbank zu löschen, bekomme ich:

ERROR:  database "pilot" is being accessed by other users
DETAIL:  There is 1 other session using the database.

Zuerst müssen Sie widerrufen

REVOKE CONNECT ON DATABASE TARGET_DB FROM public;

Dann benutze:

SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB';

Es wird sicherlich funktionieren.

77
Suneel Kumar

Prüfen Sie einfach, was die Verbindung ist und woher sie kommt. Sie können das alles in sehen:

select * from pg_stat_activity where datname = 'TARGET_DB';

Vielleicht ist es deine Verbindung?

22
user80168

Ich habe eine Lösung für dieses Problem gefunden. Versuchen Sie, diesen Befehl im Terminal auszuführen

ps -ef | grep postgres

prozess abbrechen mit diesem Befehl 

Sudo kill -9 PID
19
Dinesh Pallapa

Dies bedeutet, dass ein anderer Benutzer auf die Datenbank zugreift ... Starten Sie einfach postgresql neu. Dieser Befehl wird den Trick ausführen

[email protected]:~#Sudo service postgresql restart

Versuchen Sie dann, die Datenbank zu löschen:

postgres=# drop database test_database

Das wird den Trick tun. Glückliche Kodierung

11
Suman Astani

Wenn keine potenziellen Auswirkungen auf andere Dienste auf Ihrem Computer bestehen, service postgresql restart

8
ScotchAndSoda

pgAdmin 4 Lösung mit UI

Aktivieren Sie zunächst die Show-Aktivität im Dashboard, wenn Sie nicht:

File > Preferences > Dashboards > Display > Show Activity > true

Deaktivieren Sie nun alle Prozesse, die die Datenbankdatei verwenden:

  1. Klicken Sie auf den DB-Namen
  2. Klicken Sie auf Dashboard> Sitzungen
  3. Klicken Sie auf das Aktualisierungssymbol
  4. Klicken Sie neben jedem Prozess auf das Symbol zum Löschen (x), um sie zu beenden

Sollte jetzt die DB löschen können.

5
Andrew

In meinem Fall verwende ich AWS Redshift (basierend auf Postgres) .. und es scheint, dass keine anderen Verbindungen zur Datenbank bestehen, aber ich bekomme den gleichen Fehler.

ERROR:  database "XYZ" is being accessed by other users

In meinem Fall scheint es, als würde der Datenbankcluster noch etwas in der Datenbank verarbeitet, und obwohl es keine weiteren externen/Benutzerverbindungen gibt, wird die Datenbank intern noch verwendet. Ich habe dies gefunden, indem ich Folgendes ausgeführt habe:

SELECT * FROM stv_sessions;

Mein Hack bestand also darin, eine Schleife in meinen Code zu schreiben und nach Zeilen mit meinem Datenbanknamen zu suchen. (natürlich ist die Schleife nicht unendlich und ist eine verschlafene Schleife usw.)

SELECT * FROM stv_sessions where db_name = 'XYZ';

Wenn Zeilen gefunden werden, löschen Sie die einzelnen PIDs nacheinander.

SELECT pg_terminate_backend(PUT_PID_HERE);

Wenn keine Zeilen gefunden werden, löschen Sie die Datenbank

DROP DATABASE XYZ;

Hinweis: In meinem Fall schreibe ich Java-Einheiten-/Systemtests, bei denen dies als akzeptabel angesehen werden kann. Dies ist für Produktionscode nicht akzeptabel.


Hier ist der komplette Hack in Java (ignoriere meine Test/Utility-Klassen).

  int i = 0;
  while (i < 10) {
    try {
      i++;
      logStandardOut("First try to delete session PIDs, before dropping the DB");
      String getSessionPIDs = String.format("SELECT stv_sessions.process, stv_sessions.* FROM stv_sessions where db_name = '%s'", dbNameToReset);
      ResultSet resultSet = databaseConnection.execQuery(getSessionPIDs);
      while (resultSet.next()) {
        int sessionPID = resultSet.getInt(1);
        logStandardOut("killPID: %s", sessionPID);
        String killSessionPID = String.format("select pg_terminate_backend(%s)", sessionPID);
        try {
          databaseConnection.execQuery(killSessionPID);
        } catch (DatabaseException dbEx) {
          //This is most commonly when a session PID is transient, where it ended between my query and kill lines
          logStandardOut("Ignore it, you did your best: %s, %s", dbEx.getMessage(), dbEx.getCause());
        }
      }

      //Drop the DB now
      String dropDbSQL = String.format("DROP DATABASE %s", dbNameToReset);
      logStandardOut(dropDbSQL);
      databaseConnection.execStatement(dropDbSQL);
      break;
    } catch (MissingDatabaseException ex) {
      //ignore, if the DB was not there (to be dropped)
      logStandardOut(ex.getMessage());
      break;
    } catch (Exception ex) {
      logStandardOut("Something went wrong, sleeping for a bit: %s, %s", ex.getMessage(), ex.getCause());
      sleepMilliSec(1000);
    }
  }
2
Sagan

So einfach ist das

Sudo service postgresql restart
2
OdkoPP

Während ich die beiden Antworten mit den besten Antworten bei anderen Gelegenheiten als nützlich empfand, war es heute am einfachsten, zu erkennen, dass PyCharm eine Sitzung offen hält, und wenn ich in PyCharm auf Stop geklickt habe, könnte dies helfen. Wenn pgAdmin4 im Browser geöffnet war, tat ich dies und sah fast sofort, wie die Statistiken der Datenbanksitzungen auf 0 fielen. Zu diesem Zeitpunkt konnte ich die Datenbank löschen.

1
hlongmore

Lösung:
1. Pg Server herunterfahren
 enter image description here
2. Alle aktiven Verbindungen werden getrennt
3. Starten Sie Pg Server neu
4. Versuchen Sie es mit Ihrem Befehl

1
amoljdv06

Versuchen Sie im Terminal diesen Befehl:

ps -ef | grep postgres

sie werden sehen wie: 

501 1445 3645 0 12:05 AM 0: 00.03 postgres: sasha dbname [lokal] im Leerlauf

Die dritte Zahl (3645) ist PID. 

Sie können dies löschen 

Sudo kill -9 3645

Danach starten Sie Ihre PostgreSQL-Verbindung.

Manuell starten:

pg_ctl -D /usr/local/var/postgres start
0
Alexandr