Programing

활성 연결이있는 경우 PostgreSQL 데이터베이스를 삭제하는 방법은 무엇입니까?

lottogame 2020. 10. 3. 09:47
반응형

활성 연결이있는 경우 PostgreSQL 데이터베이스를 삭제하는 방법은 무엇입니까?


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


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

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


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.


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

Hope that is helpful. Thanks to @JustBob for the sql.


I just restart the service in Ubuntu to disconnect connected clients.

sudo service postgresql stop
sudo service postgresql start

psql
DROP DATABASE DB_NAME;

In Linux command Prompt, I would first stop all postgresql processes that are running by tying this command sudo /etc/init.d/postgresql restart

type the command bg to check if other postgresql processes are still running

then followed by dropdb dbname to drop the database

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

This works for me on linux command prompt


PostgreSQL 9.2 and above:

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


Here's my hack... =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>;"

I put this answer because include a command (above) to block new connections and because any attempt with the command...

REVOKE CONNECT ON DATABASE <DATABASE_NAME> FROM PUBLIC, <USERS_ETC>;

... do not works to block new connections!

Thanks to @araqnid @GoatWalker ! =D

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


In my case i had to execute a command to drop all connections including my active administrator connection

SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE datname = current_database()

which terminated all connections and show me a fatal ''error'' message :

FATAL: terminating connection due to administrator command SQL state: 57P01

After that it was possible to drop the database

참고URL : https://stackoverflow.com/questions/5408156/how-to-drop-a-postgresql-database-if-there-are-active-connections-to-it

반응형