PostgreSQL 데이터베이스를 삭제하는 스크립트를 작성해야합니다. 많은 연결이있을 수 있지만 스크립트는이를 무시해야합니다.
DROP DATABASE db_name
열린 연결이 있으면 표준 쿼리가 작동하지 않습니다.
문제를 어떻게 해결할 수 있습니까?
PostgreSQL 데이터베이스를 삭제하는 스크립트를 작성해야합니다. 많은 연결이있을 수 있지만 스크립트는이를 무시해야합니다.
DROP DATABASE db_name
열린 연결이 있으면 표준 쿼리가 작동하지 않습니다.
문제를 어떻게 해결할 수 있습니까?
답변:
이렇게하면 기존 연결을 제외하고 기존 연결이 끊어집니다.
pg_stat_activity
죽이고 자하는 pid 값을 쿼리 하여 얻은 다음 발행하십시오 SELECT pg_terminate_backend(pid int)
.
PostgreSQL 9.2 이상 :
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 이하 :
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();
모든 사람을 연결 해제하면 연결을 끊으려는 데이터베이스가 아닌 다른 데이터베이스의 연결에서 DROP DATABASE 명령을 연결 해제하고 발행해야합니다.
procpid
열 이름을로 바꿉니다 pid
. 이 메일 링리스트 스레드를 참조하십시오 .
; drop database TARGET_DB;
내 직전 에이 작업을 제대로 수행하면 다시 시도하기 시작했을 때 DB가 사라 졌는지 확인할 수 있습니다.
dropdb --force
입니다.
PostgreSQL 9.2 이상에서, 연결된 데이터베이스에서 세션을 제외한 모든 것을 연결 해제하려면 :
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
AND pid <> pg_backend_pid();
이전 버전에서는 동일합니다. 변경하십시오. pid
합니다 procpid
.로 하십시오 . 다른 데이터베이스 current_database()
에서 연결을 끊으려면 사용자를 연결 해제하려는 데이터베이스 이름으로 변경 하십시오.
당신은 할 수 있습니다 , 사용자를 분리하기 전에 데이터베이스의 사용자의 권리, 그렇지 않으면 사용자는 다시 연결을 계속하고 당신은 DB를 드롭 할 수있는 기회를 얻을 수 없을거야. 이 주석 과 관련된 질문 , 데이터베이스에서 다른 모든 사용자를 분리하는 방법을 참조하십시오 .REVOKE
CONNECT
유휴 사용자의 연결을 끊으려면 이 질문을 참조하십시오 .
pg_terminate_backend(int)
함수를 사용하여 데이터베이스를 삭제하기 전에 모든 연결을 종료 할 수 있습니다.
시스템보기를 사용하여 실행중인 모든 백엔드를 얻을 수 있습니다. pg_stat_activity
나는 확실하지 않지만 다음은 아마도 모든 세션을 죽일 것입니다.
select pg_terminate_backend(procpid)
from pg_stat_activity
where datname = 'doomed_database'
물론 당신은 그 데이터베이스에 자신을 연결하지 못할 수 있습니다
postgresql 버전에 따라 버그가 발생할 수 있습니다. pg_stat_activity
하여 삭제 된 사용자의 활성 연결이 생략 될 수 있습니다. 이 연결은 pgAdminIII 내부에도 표시되지 않습니다.
자동 테스트를 수행하는 경우 (사용자도 작성) 이는 가능한 시나리오 일 수 있습니다.
이 경우 다음과 같은 쿼리로 되돌려 야합니다.
SELECT pg_terminate_backend(procpid)
FROM pg_stat_get_activity(NULL::integer)
WHERE datid=(SELECT oid from pg_database where datname = 'your_database');
참고 : 9.2 이상에서는로 변경 procpid
되었습니다 pid
.
procpid
하면 pid
9.3에서 작동합니다.
postgres 9.2는 이제 procpid가 아닌 pid 열을 호출합니다.
쉘에서 호출하는 경향이 있습니다.
#!/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
도움이 되길 바랍니다. SQL을위한 @JustBob에게 감사드립니다.
Linux 명령 프롬프트에서 먼저 sudo /etc/init.d/postgresql restart 명령을 입력하여 실행중인 모든 postgresql 프로세스를 중지합니다.
다른 postgresql 프로세스가 여전히 실행 중인지 확인하려면 bg 명령을 입력하십시오.
그런 다음 dropdb dbname 다음에 데이터베이스를 삭제하십시오.
sudo /etc/init.d/postgresql restart
bg
dropdb dbname
이것은 리눅스 명령 프롬프트에서 나를 위해 작동합니다.
PostgreSQL 9.2 이상 :
SELECT pg_terminate_backend(pid)FROM pg_stat_activity WHERE datname = 'YOUR_DATABASE_NAME_HERE'
여기 내 해킹이 있습니다 ... = 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>;"
새 연결을 차단하는 명령 (위)을 포함하고 명령으로 시도 하기 때문에이 대답을 넣었습니다 ...
REVOKE CONNECT ON DATABASE <DATABASE_NAME> FROM PUBLIC, <USERS_ETC>;
... 새로운 연결을 차단하기 위해 작동하지 않습니다!
@araqnid @GoatWalker에게 감사합니다! = D
다가오는 PostgreSQL 13은 FORCE
옵션 을 소개 합니다.
DROP DATABASE 가 데이터베이스를 삭제함 ... 또한 다른 사람이 대상 데이터베이스에 연결되어 있으면 아래 설명 된 FORCE 옵션 을 사용하지 않으면이 명령이 실패 합니다.
힘
대상 데이터베이스에 대한 기존의 모든 연결을 종료하십시오. 준비된 트랜잭션, 활성 논리 복제 슬롯 또는 구독이 대상 데이터베이스에있는 경우 종료되지 않습니다.
DROP DATABASE db_name WITH (FORCE);
내 경우에는 활성 관리자 연결을 포함한 모든 연결을 삭제하는 명령을 실행해야했습니다.
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()
모든 연결이 종료되고 치명적인``오류 ''메시지가 표시됩니다.
FATAL: terminating connection due to administrator command SQL state: 57P01
그 후 데이터베이스를 삭제할 수있었습니다