Jak zrzucić bazę danych PostgreSQL, jeśli są do niej aktywne połączenia?
Muszę napisać skrypt, który upuści bazę danych PostgreSQL. Może być z nim wiele połączeń, ale skrypt powinien to zignorować.
Standardowe zapytanie DROP DATABASE db_name
nie działa, gdy istnieją otwarte połączenia.
10 answers
To usunie istniejące połączenia z wyjątkiem twojego:
Zapytanie pg_stat_activity
i pobierz wartości pid, które chcesz zabić, a następnie wydaj im SELECT pg_terminate_backend(pid int)
.
PostgreSQL 9.2 i wyżej:
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB' -- ← change this to your DB
AND pid <> pg_backend_pid();
PostgreSQL 9.1 i poniżej:
SELECT pg_terminate_backend(pg_stat_activity.procpid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TARGET_DB' -- ← change this to your DB
AND procpid <> pg_backend_pid();
Po odłączeniu wszystkich będziesz musiał odłączyć i wydać polecenie DROP DATABASE z połączenia z innej bazy danych aka nie ten, który próbujesz upuścić.
Zwróć uwagę na zmianę nazwy kolumny procpid
na pid
. Zobacz ten wątek listy dyskusyjnej .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-08 03:43:52
W PostgreSQL 9.2 i nowszych, aby odłączyć wszystko poza sesją od bazy danych, do której jesteś podłączony:
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
AND pid <> pg_backend_pid();
W starszych wersjach jest to samo, wystarczy zmienić pid
na procpid
. Aby odłączyć się od innej bazy danych, po prostu zmień current_database()
na nazwę bazy danych, z której chcesz odłączyć użytkowników.
Możesz chcieć REVOKE
CONNECT
bezpośrednio od użytkowników bazy danych przed odłączeniem użytkowników, w przeciwnym razie użytkownicy będą po prostu ponownie się łączyć i nigdy nie otrzymasz szansa na zrzucenie DB. Zobacz ten komentarz i pytanie, z którym jest związany, Jak odłączyć wszystkich innych użytkowników od bazy danych .
Jeśli chcesz po prostu odłączyć bezczynnych użytkowników, zobacz to pytanie .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:44
Można zabić wszystkie połączenia przed upuszczeniem bazy danych za pomocą funkcji pg_terminate_backend(int)
.
Możesz pobrać wszystkie uruchomione backendy używając widoku systemowego pg_stat_activity
Nie jestem do końca pewien, ale poniższe prawdopodobnie zabiłoby wszystkie sesje:
select pg_terminate_backend(procpid)
from pg_stat_activity
where datname = 'doomed_database'
Oczywiście możesz nie być podłączony do tej bazy danych
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-23 16:28:27
Zauważyłem, że postgres 9.2 nazywa teraz kolumnę pid, a nie procpid.
Zwykle nazywam to z muszli:
#!/usr/bin/env bash
# kill all connections to the postgres server
if [ -n "$1" ] ; then
where="where pg_stat_activity.datname = '$1'"
echo "killing all connections to database '$1'"
else
echo "killing all connections to database"
fi
cat <<-EOF | psql -U postgres -d postgres
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
${where}
EOF
Mam nadzieję, że to pomoże. Dzięki @JustBob za sql.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-23 03:35:17
W zależności od wersji postgresql może pojawić się błąd, który sprawia, że pg_stat_activity
pomija aktywne połączenia od usuniętych użytkowników. Połączenia te również nie są pokazane wewnątrz pgAdminIII.
Jeśli wykonujesz automatyczne testy (w których również tworzysz użytkowników), może to być prawdopodobny scenariusz.
W tym przypadku musisz powrócić do zapytań typu:
SELECT pg_terminate_backend(procpid)
FROM pg_stat_get_activity(NULL::integer)
WHERE datid=(SELECT oid from pg_database where datname = 'your_database');
Uwaga: w 9.2+ będziesz miał zmianę procpid
na pid
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-11 09:53:25
W wierszu polecenia Linuksa, najpierw zatrzymałbym wszystkie uruchomione procesy postgresql, wiążąc to polecenie sudo /etc / init.d / postgresql restart
Wpisz polecenie bg aby sprawdzić, czy inne procesy postgresql nadal działają
Następnie dropdb dbname aby upuścić bazę danych
sudo /etc/init.d/postgresql restart
bg
dropdb dbname
To działa dla mnie w Linuksie wiersz polecenia
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-29 07:55:10
Po prostu restartuję usługę w Ubuntu, aby odłączyć podłączonych klientów.
sudo service postgresql stop
sudo service postgresql start
psql
DROP DATABASE DB_NAME;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-13 20:03:12
PostgreSQL 9.2 i wyżej:
SELECT pg_terminate_backend(pid)FROM pg_stat_activity WHERE datname = 'YOUR_DATABASE_NAME_HERE'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-22 17:39:23
Oto mój haczyk... =D
# Make sure no one can connect to this database except you!
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "UPDATE pg_database SET datallowconn=false WHERE datname='<DATABASE_NAME>';"
# Drop all existing connections except for yours!
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '<DATABASE_NAME>' AND pid <> pg_backend_pid();"
# Drop database! =D
sudo -u postgres /usr/pgsql-9.4/bin/psql -c "DROP DATABASE <DATABASE_NAME>;"
Umieściłem tę odpowiedź, ponieważ zawiera polecenie (powyżej) blokujące nowe połączenia i Ponieważ każda próba użycia polecenia ...
REVOKE CONNECT ON DATABASE <DATABASE_NAME> FROM PUBLIC, <USERS_ETC>;
... nie działa blokowanie nowych połączeń!
Dzięki @ araqnid @ GoatWalker ! =DWarning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-20 13:23:22
W moim przypadku musiałem wykonać polecenie, aby usunąć wszystkie połączenia, w tym moje aktywne połączenie administratora
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
Który przerwał wszystkie połączenia i pokazał mi fatalny komunikat "Błąd":
FATAL: terminating connection due to administrator command SQL state: 57P01
Po tym można było porzucić bazę danych
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-02 10:55:14