Как сбросить все соединения с определенной базой данных, не останавливая сервер?

45

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

Как я могу это сделать?

Сорин
источник
Я где-то читал, что вы можете использовать lowth.com/cutter для достижения этой цели .

Ответы:

22

Вот мой ответ на очень похожий вопрос о StackOverflow.

В зависимости от вашей версии postgresql вы можете столкнуться с ошибкой, из- pg_stat_activityза которой пропускаются активные соединения от сброшенных пользователей. Эти соединения также не показаны внутри pgAdminIII.

Если вы выполняете автоматическое тестирование (в котором вы также создаете пользователей), это может быть вероятным сценарием.

В этом случае вам нужно вернуться к таким запросам, как:

 SELECT pg_terminate_backend(pg_stat_activity.procpid) 
 FROM pg_stat_get_activity(NULL::integer) 
 WHERE datid=(SELECT oid from pg_database where datname = 'your_database');
ДБ.
источник
8
ОШИБКА: отсутствует запись в предложении FROM для таблицы "pg_stat_activity" (psql (9.6.1))
user1767316
4
это больше не работает .... получите вышеуказанную ошибку ^
легкий
Смотрите ответ Шимона Гуза ниже
Dfranc3373
Отсутствует от пункта, не работает
Vipul
78

Такой запрос должен помочь (при условии, что база данных называется 'db'):

select pg_terminate_backend(pid) from pg_stat_activity where datname='db';

pidРаньше вызывали procpid, так что если вы используете версию postgres старше 9.2, вы можете попробовать следующее:

select pg_terminate_backend(procpid) from pg_stat_activity where datname='db';

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

Это также может быть полезно REVOKE CONNECT ON DATABASE FROM PUBLICили что-то подобное, а потом GRANTэто потом.

Пол Уайт говорит, что GoFundMonica
источник
3

Это можно использовать для «освобождения» базы данных от клиентских подключений, чтобы вы, например, могли ее переименовать:

SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname='current_db';
ALTER DATABASE current_db RENAME TO old_db;
ALTER DATABASE new_db RENAME TO current_db;

Помните, что это может вызвать проблемы в ваших клиентских приложениях. Фактически данные не должны прерываться из-за использования транзакций.

Trygve Laugstøl
источник