Подтвердить что ты не робот

Postgresql - невозможно удалить базу данных из-за некоторых автоматических подключений к БД

Всякий раз, когда я пытаюсь удалить базу данных, я получаю:

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

Когда я использую:

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

Я прекратил соединение с этой БД, но если я попытаюсь удалить базу данных после этого, как-то кто-то автоматически подключится к этой базе данных и даст эту ошибку. Что это может сделать? Никто не использует эту базу данных, кроме меня.

4b9b3361

Ответ 1

Вы можете предотвратить будущие подключения:

REVOKE CONNECT ON DATABASE thedb FROM public;

(и, возможно, другие пользователи/роли, см. \l+ в psql)

Затем вы можете завершить все подключения к этому db, кроме своего собственного:

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

В старых версиях pid был вызван procpid, поэтому вам придется иметь дело с этим.

Поскольку вы отменили права CONNECT, все, что пыталось автосоединить, больше не сможет этого сделать.

Теперь вы сможете удалить базу данных.

Это не сработает, если вы используете подключения суперпользователя для обычных операций, но если вы это сделаете, вам нужно сначала исправить эту проблему.

Ответ 2

Всякий раз, когда я пытаюсь удалить базу данных, я получаю:

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

Сначала вам нужно отменить

REVOKE CONNECT ON DATABASE TARGET_DB FROM public;

Затем используйте:

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

Это, безусловно, будет работать.

Ответ 3

Просто проверьте, что такое соединение, откуда оно. Вы можете увидеть все это в:

select * from pg_stat_activity where datname = 'TARGET_DB';

Возможно, это ваша связь?

Ответ 4

Я нашел решение этой проблемы, попробую запустить эту команду в терминале

ps -ef | grep postgres

убить процесс с помощью этой команды

sudo kill -9 PID

Ответ 5

Если никакого потенциального влияния на другие службы на вашем компьютере, просто service postgresql restart

Ответ 6

Это означает, что другой пользователь обращается к базе данных... Просто перезапустите postgresql. Эта команда сделает трюк

[email protected]:~#sudo service postgresql restart

Затем попробуйте удалить базу данных:

postgres=# drop database test_database

Это сделает трюк. Счастливое кодирование

Ответ 7

Решение pgAdmin 4 с использованием пользовательского интерфейса

Сначала включите отображение активности на панели управления, если у вас ее нет:

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

Теперь отключите все процессы, используя db:

  1. Нажмите имя базы данных
  2. Нажмите "Панель мониторинга"> "Сессии"
  3. Нажмите значок обновления
  4. Нажмите значок delete (x) рядом с каждым процессом, чтобы закончить их

Теперь можно удалить db.

Ответ 8

Просто как тот

sudo service postgresql restart

Ответ 9

В моем случае я использую AWS Redshift (на основе Postgres). И, похоже, нет никаких других связей с БД, но я получаю эту же ошибку.

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

В моем случае, похоже, кластер базы данных все еще выполняет некоторую обработку в базе данных, и, хотя других внешних/пользовательских подключений нет, база данных по-прежнему используется внутри страны. Я нашел это, выполнив следующее:

SELECT * FROM stv_sessions;

Поэтому мой взлом заключался в том, чтобы написать цикл в моем коде, ища строки с моим именем базы данных. (конечно, цикл не бесконечен и является сонным контуром и т.д.),

SELECT * FROM stv_sessions where db_name = 'XYZ';

Если найдены строки, продолжайте удалять каждый PID один за другим.

SELECT pg_terminate_backend(PUT_PID_HERE);

Если строк не найдено, перейдите в базу данных

DROP DATABASE XYZ;

Примечание. В моем случае я пишу тесты на Java/систему, где это можно считать приемлемым. Это недопустимо для производственного кода.


Вот полный хак, в Java (игнорируйте мои тестовые/служебные классы).

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

Ответ 10

В терминале попробуйте выполнить следующую команду:

ps -ef | grep postgres

вы увидите:

501 1445 3645 0 12:05 0: 00.03 postgres: sasha dbname [local] idle

Третье число (3645) является PID.

Вы можете удалить это

sudo kill -9 3645

И после этого запустите соединение PostgreSQL.

Запуск вручную:

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

Ответ 11

Решение:
1. Завершить работу Pg-сервера
enter image description here
2. Отключите все активные соединения
3. Перезагрузите Pg-сервер
4. Попробуйте выполнить команду