如何删除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
在我的情况下,我不得不执行命令来删除所有连接,包括我的活动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;