답변:
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 단계 에는 첫 번째 방법에 대한 수퍼 유저 권한과 두 번째 방법에 대한 데이터베이스 소유자 권한이 필요합니다. 2 단계에는 수퍼 유저 권한이 필요합니다 . 3 단계에는 데이터베이스 소유자 권한이 필요 합니다 .
* 이것은 모든 버전의 PostgreSQL, 버전 11까지 적용됩니다.
이 인 쉘 유틸리티를 사용하여이 작업을 수행 할 수있는 방법 dropdb
및 pg_ctl
(또는 pg_ctlcluster
데비안 및 유도체 인은). 그러나 @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
데이터베이스가없는 연결을 선택하여 DB에 연결 한 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;