활성화 된 PostgreSQL 데이터베이스가 있다면 어떻게 삭제합니까?


648

PostgreSQL 데이터베이스를 삭제하는 스크립트를 작성해야합니다. 많은 연결이있을 수 있지만 스크립트는이를 무시해야합니다.

DROP DATABASE db_name열린 연결이 있으면 표준 쿼리가 작동하지 않습니다.

문제를 어떻게 해결할 수 있습니까?


1
현재 어떤 PostgreSQL 버전을 사용하고 있습니까?
Kuberchaun

1
문제점 : 데이터베이스에 연결된 세션을 종료 할 수 있지만 세션을 너무 빨리 다시 연결하여 데이터베이스를 삭제할 수 없습니다. 행복하게도이 게시물은 새로운 연결을 잠그는 방법을 보여줍니다. 따라서 현재 연결을 끊고
Max Murphy

1
dba.stackexchange 에서이 답변이 dba.stackexchange.com/a/11895/163539에 매우 유용 하다는 것을 알았습니다 . 간결하지만 충분히 설명이 필요합니다.
hlongmore

답변:


1093

이렇게하면 기존 연결을 제외하고 기존 연결이 끊어집니다.

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. 이 메일 링리스트 스레드를 참조하십시오 .


11
물론 'TARGET_DB'에 대한 연결이 아닌 DB 연결 에서이 작업을 수행해야합니다. 그렇지 않으면 'ERROR'가 발생합니다. 'postgres'연결이 잘 작동합니다.

3
실제로 클라이언트를 하나씩 연결 해제하고 클라이언트가 목록의 중간에 있으면 연결이 끊어집니다. 결과적으로 일부 연결은 활성 상태로 유지됩니다. 그래서 정답은 Craig Ringer (아래 참조)입니다. pg_stat_activity에서 pg_terminate_backend (pg_stat_activity.pid)를 선택하십시오. 여기서 datname = current_database () AND pg_stat_activity.pid <> pg_backend_pid ();
앤드류 셀리 야 노프

1
현재 트랜잭션을 완료 한 후 연결을 끊은 다음 문제가되는 테이블을 삭제하려면 어떻게해야합니까?
paulkon

5
내 경우에는 클라이언트가 빠르게 다시 연결되므로 ; drop database TARGET_DB;내 직전 에이 작업을 제대로 수행하면 다시 시도하기 시작했을 때 DB가 사라 졌는지 확인할 수 있습니다.
Mat Schaffer

1
나는 심지어 돈을 지불 할 것 dropdb --force입니다.
Torsten Bronger

125

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를 드롭 할 수있는 기회를 얻을 수 없을거야. 이 주석 과 관련된 질문 , 데이터베이스에서 다른 모든 사용자를 분리하는 방법을 참조하십시오 .REVOKECONNECT

유휴 사용자의 연결을 끊으려면 이 질문을 참조하십시오 .


3
pg_stat_activity에서 pg_terminate_backend (pg_stat_activity.pid)를 선택하십시오. 여기서 datname = current_database () AND pg_stat_activity.pid <> pg_backend_pid ();
Andrew Selivanov

26

pg_terminate_backend(int)함수를 사용하여 데이터베이스를 삭제하기 전에 모든 연결을 종료 할 수 있습니다.

시스템보기를 사용하여 실행중인 모든 백엔드를 얻을 수 있습니다. pg_stat_activity

나는 확실하지 않지만 다음은 아마도 모든 세션을 죽일 것입니다.

select pg_terminate_backend(procpid)
from pg_stat_activity
where datname = 'doomed_database'

물론 당신은 그 데이터베이스에 자신을 연결하지 못할 수 있습니다


19

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.


1
Ths는 내가 찾고 있었지만 (9.2 이상 가정) pg_stat_activity에 대한 참조를 제거하고 procpid를 pid로 변경해야합니다.
MDR

2
이 스 니펫으로 변경 procpid하면 pid9.3에서 작동합니다.
jb.

pg_stat_activity를 제거하지 않고도? 9.2
MDR

확인. 이제는 오타였습니다. 감사!
jb.

2
9.3 이상에서 SELECT pg_terminate_backend (pid) FROM pg_stat_get_activity (NULL :: integer) WHERE datid = (pg_database에서 oid 선택)
Shawn Vader

17

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에게 감사드립니다.


15

우분투에서 서비스를 다시 시작하여 연결된 클라이언트의 연결을 끊습니다.

sudo service postgresql stop
sudo service postgresql start

psql
DROP DATABASE DB_NAME;

10

Linux 명령 프롬프트에서 먼저 sudo /etc/init.d/postgresql restart 명령을 입력하여 실행중인 모든 postgresql 프로세스를 중지합니다.

다른 postgresql 프로세스가 여전히 실행 중인지 확인하려면 bg 명령을 입력하십시오.

그런 다음 dropdb dbname 다음에 데이터베이스를 삭제하십시오.

sudo /etc/init.d/postgresql restart
bg
dropdb dbname

이것은 리눅스 명령 프롬프트에서 나를 위해 작동합니다.


6
데이터베이스가 많고 단일 DB에 대한 연결 만 삭제하려는 경우에는 좋지 않습니다. 이렇게하면 모든 연결이 끊어집니다. 조금 "썰매 망치"입니다.
Nick

2
사실 @Nick하지만 우리는 모든 연결을 다시 시작하고 완전히 중지하는 기억
모리스 Elagu을

10

PostgreSQL 9.2 이상 :

SELECT pg_terminate_backend(pid)FROM pg_stat_activity WHERE datname = 'YOUR_DATABASE_NAME_HERE'


그게 활성화 된 연결을 종료하지 않습니까?
Cocowalla 19

8

여기 내 해킹이 있습니다 ... = 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

https://stackoverflow.com/a/3185413/3223785


5

다가오는 PostgreSQL 13은 FORCE옵션 을 소개 합니다.

DROP 데이터베이스

DROP DATABASE 가 데이터베이스를 삭제함 ... 또한 다른 사람이 대상 데이터베이스에 연결되어 있으면 아래 설명 된 FORCE 옵션 을 사용하지 않으면이 명령이 실패 합니다.

대상 데이터베이스에 대한 기존의 모든 연결을 종료하십시오. 준비된 트랜잭션, 활성 논리 복제 슬롯 또는 구독이 대상 데이터베이스에있는 경우 종료되지 않습니다.

DROP DATABASE db_name WITH (FORCE);

0

내 경우에는 활성 관리자 연결을 포함한 모든 연결을 삭제하는 명령을 실행해야했습니다.

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

그 후 데이터베이스를 삭제할 수있었습니다


0

pgAdmin4를 사용하여 로그인하고 대시 보드에서 pgAdmin4를 제외한 모든 연결을 끊은 다음 데이터베이스와 속성을 마우스로 핥아 새 이름을 입력하여 이름을 바꿀 수 있다는 점을 제외하고는 아무것도 효과가 없었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.