Я хочу відмовитись від усіх з'єднань (сеансів), які зараз відкриті до певної бази даних PostgreSQL, але без перезавантаження сервера або відключення з'єднань з іншими базами даних.
Як я можу це зробити?
Я хочу відмовитись від усіх з'єднань (сеансів), які зараз відкриті до певної бази даних PostgreSQL, але без перезавантаження сервера або відключення з'єднань з іншими базами даних.
Як я можу це зробити?
Відповіді:
Ось моя відповідь на дуже схоже запитання щодо 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');
Цей запит повинен допомогти (припустимо, що база даних має ім'я 'db'):
select pg_terminate_backend(pid) from pg_stat_activity where datname='db';
pid
колись називали procpid
, тож якщо ви використовуєте версію поштових знаків старші 9,2, ви можете спробувати наступне:
select pg_terminate_backend(procpid) from pg_stat_activity where datname='db';
Однак ви повинні бути супер-користувачем, щоб відключити інших користувачів.
Також це може бути корисним REVOKE CONNECT ON DATABASE FROM PUBLIC
чи чимось подібним, а потім - GRANT
згодом.
Це можна використовувати для "звільнення" бази даних від клієнтських з'єднань, так що ви, наприклад, можете перейменувати її:
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;
Майте на увазі, що це може спричинити проблематичну поведінку для ваших клієнтських програм. Дані фактично не повинні бути зірвані через використання транзакцій.