Chcę usunąć wszystkie połączenia (sesje), które są obecnie otwarte dla określonej bazy danych PostgreSQL, ale bez ponownego uruchamiania serwera lub rozłączania połączeń z innymi bazami danych.
Jak mogę to zrobić?
Chcę usunąć wszystkie połączenia (sesje), które są obecnie otwarte dla określonej bazy danych PostgreSQL, ale bez ponownego uruchamiania serwera lub rozłączania połączeń z innymi bazami danych.
Jak mogę to zrobić?
Odpowiedzi:
Oto moja odpowiedź na bardzo podobne pytanie na StackOverflow.
W zależności od wersji postgresql możesz napotkać błąd, który powoduje pg_stat_activity
pominięcie aktywnych połączeń od upuszczonych użytkowników. Te połączenia również nie są pokazane w pgAdminIII.
Jeśli wykonujesz testy automatyczne (w których również tworzysz użytkowników), może to być prawdopodobny scenariusz.
W takim przypadku musisz wrócić do zapytań takich jak:
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');
Takie zapytanie powinno pomóc (zakładając, że baza danych nosi nazwę „db”):
select pg_terminate_backend(pid) from pg_stat_activity where datname='db';
pid
był wywoływany procpid
, więc jeśli używasz wersji postgres starszej niż 9.2, możesz spróbować:
select pg_terminate_backend(procpid) from pg_stat_activity where datname='db';
Jednak musisz być superużytkownikiem, aby rozłączyć innych użytkowników.
Może być również przydatny REVOKE CONNECT ON DATABASE FROM PUBLIC
lub podobny, a potem GRANT
później.
Można tego użyć do „zwolnienia” bazy danych z połączeń klienckich, aby na przykład można zmienić jej nazwę:
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;
Pamiętaj, że może to powodować problematyczne zachowanie aplikacji klienckich. W rzeczywistości dane nie powinny być zakłócane z powodu korzystania z transakcji.