Câu trả lời:
Trong PostgreSQL * , bạn không thể bỏ cơ sở dữ liệu trong khi máy khách được kết nối với nó.
Ít nhất, không phải với dropdb
tiện ích - mà chỉ là một trình bao bọc đơn giản xung quanh DROP DATABASE
truy vấn máy chủ.
Cách giải quyết khá mạnh mẽ sau:
Kết nối với máy chủ của bạn dưới dạng siêu người dùng , sử dụng psql
hoặc ứng dụng khách khác. Đừng không sử dụng cơ sở dữ liệu bạn muốn thả.
psql -h localhost postgres postgres
Bây giờ bằng cách sử dụng máy khách cơ sở dữ liệu đơn giản, bạn có thể buộc thả cơ sở dữ liệu bằng ba bước đơn giản:
Hãy chắc chắn rằng không ai có thể kết nối với cơ sở dữ liệu này. Bạn có thể sử dụng một trong các phương pháp sau (cách thứ hai có vẻ an toàn hơn, nhưng không ngăn chặn kết nối từ siêu nhân).
/* 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; */
Buộc ngắt kết nối tất cả các máy khách được kết nối với cơ sở dữ liệu này, bằng cách sử dụng 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'; */
Thả cơ sở dữ liệu.
DROP DATABASE mydb;
Bước 1 yêu cầu đặc quyền siêu người dùng cho phương thức 1 và đặc quyền chủ sở hữu cơ sở dữ liệu cho phương thức thứ hai. Bước 2 yêu cầu đặc quyền siêu người dùng . Bước 3 yêu cầu đặc quyền chủ sở hữu cơ sở dữ liệu .
* Điều này áp dụng cho tất cả các phiên bản của PostgreSQL, cho đến phiên bản 11.
Có là một cách để làm điều này với các tiện ích vỏ dropdb
& pg_ctl
(hoặc pg_ctlcluster
trong Debian và derivates). Nhưng phương pháp của @ filiprem là vượt trội vì nhiều lý do:
dropdb
lệnh.Tôi trích dẫn man pg_ctlcluster
:
Với
--force
tùy chọn, chế độ "nhanh" được sử dụng để khôi phục tất cả các giao dịch đang hoạt động, ngắt kết nối khách hàng ngay lập tức và do đó tắt hoàn toàn. Nếu điều đó không hoạt động, tắt máy được thử lại ở chế độ "ngay lập tức", điều này có thể khiến cụm ở trạng thái không nhất quán và do đó sẽ dẫn đến quá trình khôi phục ở lần khởi động tiếp theo. Nếu điều này vẫn không giúp ích, quá trình bưu điện bị giết. Thoát với 0 khi thành công, với 2 nếu máy chủ không chạy và với 1 trên các điều kiện lỗi khác. Chế độ này chỉ nên được sử dụng khi máy sắp tắt.
pg_ctlcluster 9.1 main restart --force
hoặc là
pg_ctl restart -D datadir -m fast
hoặc là
pg_ctl restart -D datadir -m immediate
ngay lập tức theo sau:
dropdb mydb
Có thể trong một kịch bản cho sự thành công ngay lập tức.
Sử dụng câu trả lời của @ filiprem trong trường hợp của tôi và đơn giản hóa nó:
-- 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
Nếu bạn đang sử dụng RDS, nơi các kết nối không có cơ sở dữ liệu được chọn sẽ đưa bạn vào DB mà bạn yêu cầu được tạo theo mặc định, bạn có thể thực hiện biến thể này để nhận ra mình là kết nối mở cuối cùng.
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;