如何删除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' 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' 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()更改为要断开用户连接的数据库的名称即可。

您可能需要在断开用户连接之前从数据库用户的REVOKE CONNECT权限,否则用户将只是继续重新连接,你永远不会有机会丢弃数据库。 看到这个评论和它的相关问题, 我如何从数据库中分离所有其他用户 。

如果您只想断开闲置的用户,请参阅此问题 。

在使用pg_terminate_backend(int)函数删除数据库之前,可以pg_terminate_backend(int)所有连接。

您可以使用系统视图pg_stat_activity来获取所有正在运行的后端

我不完全确定,但以下可能会杀死所有会议:

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

当然,你可能没有把自己连接到这个数据库

我注意到postgres 9.2现在调用列pid而不是procpid。

我倾向于从shell中调用它:

 #!/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 

希望有帮助。 感谢@JustBob的SQL。

根据您的postgresql版本,您可能会遇到一个错误,使得pg_stat_activity忽略掉线用户的活动连接。 这些连接也不会显示在pgAdminIII中。

如果您正在进行自动testing(您也在其中创build用户),这可能是一个可能的情况。

在这种情况下,您需要恢复如下查询:

  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

在Linux命令提示符下,我将首先停止所有通过绑定此命令运行的postgresql进程sudo /etc/init.d/postgresql restart

键入命令bg来检查其他postgresql进程是否仍在运行

然后是dropdb dbname来删除数据库

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

这对我在Linux命令提示符下工作

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

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

在我的情况下,我不得不执行命令来删除所有连接,包括我的活动pipe理员连接

 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

之后,可以删除数据库

我只是在Ubuntu重新启动服务断开连接的客户端。

 sudo service postgresql stop sudo service postgresql start psql DROP DATABASE DB_NAME;