如何在不停止服务器的情况下删除与特定数据库的所有连接?

sor*_*rin 77 postgresql session connections

我想删除当前打开到特定 PostgreSQL 数据库的所有连接(会话),但不重新启动服务器或断开与其他数据库的连接。

我怎样才能做到这一点?

小智 133

这样的查询应该会有所帮助(假设数据库名为“db”):

select pg_terminate_backend(pid) from pg_stat_activity where datname='db';
Run Code Online (Sandbox Code Playgroud)

pid曾经被称为procpid,因此如果您使用的是早于 9.2 的 postgres 版本,您可以尝试以下操作:

select pg_terminate_backend(procpid) from pg_stat_activity where datname='db';
Run Code Online (Sandbox Code Playgroud)

但是,您必须是超级用户才能断开其他用户的连接。

它也可能对REVOKE CONNECT ON DATABASE FROM PUBLIC或类似的东西有用,然后再使用GRANT


小智 35

这是我对 StackOverflow 上非常相似的问题的回答。

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

如果您正在进行自动测试(您还创建用户),这可能是一个可能的场景。

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

 SELECT pg_terminate_backend(pg_stat_activity.procpid) 
 FROM pg_stat_get_activity(NULL::integer) 
 WHERE datid=(SELECT oid from pg_database where datname = 'your_database');
Run Code Online (Sandbox Code Playgroud)

  • 错误:缺少表“pg_stat_activity”的 FROM 子句条目(psql(9.6.1)) (22认同)
  • 这不再起作用了....得到上述错误^ (4认同)
  • 这对我有用,@Szymon Guz 的解决方案现在应该是公认的答案:`select pg_terminate_backend(pid) from pg_stat_activity where datname='DB_NAME';` (2认同)

小智 5

这可用于从客户端连接中“释放”数据库,例如,您可以重命名它:

SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname='current_db';
ALTER DATABASE current_db RENAME TO old_db;
ALTER DATABASE new_db RENAME TO current_db;
Run Code Online (Sandbox Code Playgroud)

请注意,这可能会导致客户端应用出现问题。数据实际不应该因为使用事务而被破坏。