Как мне отсоединить всех других пользователей от базы данных postgres?


13

Мне нужен эксклюзивный доступ к базе данных. Возможно ли использовать команду SQL для «отсоединения» всех других пользователей от базы данных postgres. Или, может быть, закрыть все другие соединения и затем получить эксклюзивный доступ.

Это для модульного тестирования, и тесты выполняются только вручную, поэтому опасности нет. Будут затронуты только старые мертвые соединения.

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

Старые мертвые связи происходят из развития. Это происходит все время, когда тест, который пишется или не проходит, не завершается без ошибок.


Если кому-то также необходимо временно заблокировать других пользователей после их отключения в производственном сценарии, см. Ответ Скотта Марлоу ниже: /dba//a/6184/2024


Смотрите также этот похожий вопрос на dba: Как отбросить все соединения с определенной базой данных, не останавливая сервер?

Ответы:


14

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

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

Обновление Еще лучший запрос избавляет от подвыбора:

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

2
не забудьте отозвать разрешения CONNECT, в противном случае пользователи создают новые подключения, прежде чем у вас будет эксклюзивный доступ.
Фрэнк Хайкенс

@Frank Heikens - Хороший улов. Я включил «ручной модульный тест», но если есть другие подключающиеся, кроме того, кто выполняет модульный тест, то «отменить подключение к <имя_сайта> из ...» будет необходимо.
gsiems

В PostgreSQL 9.2 procpidбыл переименован в pid, так что следите за этим.
Крейг Рингер

Помимо REVOKE с данным пользователем, мне также пришлось REVOKE ..... public - что-то, на что нужно обратить внимание!
Дэвид Н. Велтон,

в 9.3 кажется, что pg_stat_activity.procpid теперь называется pg_stat_activity.pid . работал хорошо в противном случае.
JL Peyret

4

Проблема здесь двоякая: во-первых, вам нужно отключить этих пользователей, а во-вторых, вы должны держать их подальше от вашего сервера. Вместо отмены разрешений на подключение я обычно использую pg_hba.conf для отказа в новых подключениях от определенных машин и / или пользователей, а затем просто делаю быструю остановку pg_ctl -m; pg_ctl начинает сбрасывать все текущие подключения. С slony, делающим изменения DDL, это в значительной степени необходимо, или вы будете получать тупики повсюду.


5
Я всегда использую одну роль, которая позволяет CONNECT и наследуется всеми другими ролями. REVOKE подключиться к этой единственной роли, и все готово. Оберните его в функцию с помощью pg_terminate_backend (), и вы сможете контролировать все текущие соединения.
Фрэнк Хейкенс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.