Відповіді:
У PostgreSQL * ви не можете скинути базу даних, поки клієнти підключені до неї.
Принаймні, не з dropdb
утилітою - яка є лише простою обгорткою навколо DROP DATABASE
запиту сервера.
Досить надійний спосіб вирішення:
Підключіться до свого сервера як суперпользователь , користувач psql
або інший клієнт. Як НЕ використовувати базу даних , яку ви хочете відмовитися.
psql -h localhost postgres postgres
Тепер, використовуючи звичайний клієнт бази даних, ви можете змусити випадати базу даних за допомогою трьох простих кроків:
Переконайтесь, що ніхто не може підключитися до цієї бази даних. Можна скористатися одним із наступних методів (другий здається більш безпечним, але не перешкоджає з'єднанню суперпользователей).
/* Method 1: update system catalog */
UPDATE pg_database SET datallowconn = 'false' WHERE datname = 'mydb';
/* Method 2: use ALTER DATABASE. Superusers still can connect!
ALTER DATABASE mydb CONNECTION LIMIT 0; */
Примусове відключення всіх клієнтів, підключених до цієї бази даних, за допомогою pg_terminate_backend
.
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'mydb';
/* For old versions of PostgreSQL (up to 9.1), change pid to procpid:
SELECT pg_terminate_backend(procpid)
FROM pg_stat_activity
WHERE datname = 'mydb'; */
Відкиньте базу даних.
DROP DATABASE mydb;
Крок 1 вимагає привілеїв суперпользователя для 1-го методу, а права власника бази даних - для другого. Крок 2 вимагає привілеїв суперпользователя . Крок 3 вимагає права власника бази даних .
* Це стосується всіх версій PostgreSQL, аж до версії 11.
Там є спосіб зробити це з допомогою утиліти оболонки dropdb
і pg_ctl
(або pg_ctlcluster
в Debian і дериватів). Але метод @ filiprem є кращим з кількох причин:
dropdb
команду.Цитую man pg_ctlcluster
:
За допомогою
--force
опції використовується режим "швидкого", який відкидає всі активні транзакції, негайно відключає клієнтів і таким чином вимикається чисто. Якщо це не допоможе, спробу відключення спробують знову в режимі "негайного", що може залишити кластер у непослідовному стані і, таким чином, призведе до запуску відновлення при наступному запуску. Якщо це все-таки не допомагає, процес поштового зв’язку вбивається. Виходить з 0 на успіх, з 2, якщо сервер не працює, і з 1 в інших умовах відмови. Цей режим слід використовувати лише тоді, коли машина збирається вимкнути.
pg_ctlcluster 9.1 main restart --force
або
pg_ctl restart -D datadir -m fast
або
pg_ctl restart -D datadir -m immediate
одразу слідує:
dropdb mydb
Можливо, в сценарії для негайної спадкоємності.
Використання @ filiprem відповіді в моєму випадку та спрощення її:
-- Connecting to the current user localhost's postgres instance
psql
-- Making sure the database exists
SELECT * from pg_database where datname = 'my_database_name'
-- Disallow new connections
UPDATE pg_database SET datallowconn = 'false' WHERE datname = 'my_database_name';
ALTER DATABASE my_database_name CONNECTION LIMIT 1;
-- Terminate existing connections
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'my_database_name';
-- Drop database
DROP DATABASE my_database_name
Якщо у вас є щось на зразок RDS, коли з'єднання без обраної бази даних вводять вас у БД, яку ви просили створити за замовчуванням, ви можете виконати цей варіант, щоб обійти себе останнім відкритим з'єднанням.
DROP DATABASE IF EXISTS temporary_db_that_shouldnt_exist;
CREATE DATABASE temporary_db_that_shouldnt_exist with OWNER your_user;
\connect temporary_db_that_shouldnt_exist
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'the_db_you_want_removed';
DROP DATABASE IF EXISTS the_db_you_want_removed;
--
-- Name: the_db_you_want_removed; Type: DATABASE; Schema: -; Owner: your_user
--
CREATE DATABASE savings_champion WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8';
ALTER DATABASE the_db_you_want_removed OWNER TO your_user;
\connect the_db_you_want_removed
DROP DATABASE IF EXISTS temporary_db_that_shouldnt_exist;