Heroku Postgres:连接太多。我该如何结束这些连接?

58

我有一个应用程序在Heroku上运行。 这个应用程序安装了Postgres 9.2.4(Dev)插件。 为了访问我的在线数据库,我使用Navicat Postgres。 有时,Navicat不能完全关闭与Postgres数据库建立的连接。 结果是,在一段时间后,有20多个打开的连接到Postgres数据库。 我的Postgres安装只允许20个同时连接。 因此,由于20多个打开的连接,我的Postgress数据库现在无法访问(连接太多)。

我知道这是Navicat的问题,我正在尝试在那方面解决这个问题。 但如果发生这种情况(连接太多),我该如何解决(例如关闭所有连接)。

我尝试了以下所有操作,但没有结果:

  • 关闭Navicat并重新启动计算机(OS X 10.9)
  • 重新启动Heroku应用程序(heroku restart
  • 尝试重启在线数据库,但我发现没有这个选项
  • 手动关闭从OS X到Postgres服务器IP的所有连接
  • 重启我们的路由器

我认为在Postgres这边存在一些“死”连接是很明显的。 但是,我怎样才能关闭它们呢?

6个回答

46

好的,这看起来比我发布的更有用。 - bma
7
这是解决方法。谢谢。这里有点讽刺。当我执行 heroku pg 命令时,它告诉我有 21 个连接处于打开状态(20 是最大值),所以当我执行 heroku pg:killall DATABASE_NAME 命令时,它报错说无法连接并执行命令,因为所有连接都被占用了。所以我必须等待其中一个连接超时。:( - Jasper Schulte
1
如果你遇到了@Zjaaspoer的问题,重新启动你的Heroku应用程序,这可能会释放一个连接,让你运行kill命令。 - Jamon Holmgren

25

heroku pg:killall会终止所有打开的连接,但这可能对您的需求来说是一种粗暴的方法。有趣的是,您可以使用heroku的dataclips实际上杀死特定的连接。

要获取连接的详细列表,您可以通过dataclips进行查询:

SELECT * FROM pg_stat_activity;

在某些情况下,您可能希望终止与特定IP地址关联的所有连接(例如您的笔记本电脑或者在我这种情况下是一个已经被破坏的服务器)。

您可以使用以下命令查看每个客户端IP地址拥有的连接数量:

SELECT client_addr, count(*) 
FROM pg_stat_activity 
WHERE client_addr is not null 
  AND client_addr <> (select client_addr from pg_stat_activity where pid=pg_backend_Tid()) 
GROUP BY client_addr; 

该命令将列出每个IP的连接数,不包括dataclips本身使用的IP。

要实际终止连接,您需要将其“pid”传递给pg_terminate_backend()。在简单情况下:

SELECT pg_terminate_backend(1234)

在pg_stat_activity中找到的1234是有问题的PID。

在我的情况下,我想关闭所有与(已经死亡的)服务器相关的连接,所以我使用了:

SELECT pg_terminate_backend(pid), host(client_addr) 
FROM pg_stat_activity 
WHERE host(client_addr) = 'IP HERE'

12

1). 使用正确的ID(如果您有多个帐户)登录Heroku,使用heroku login命令。
2). 然后运行heroku apps命令,获取您应用程序的列表,并复制其中安装了PostgreSQL数据库的应用程序的名称。
3). 最后,运行heroku pg:killall --app appname命令以终止所有连接。


9
Heroku文档(重点在我这里):
致命错误:角色的连接数过多
对于启动版(Dev和Basic)计划,每个用户的最大连接限制为20个。 要解决此错误,请通过停止后台工作程序、减少dynos的数量或重新启动应用程序(如果它随着时间的推移创建了连接泄漏)来关闭一些与数据库的连接。在Rails应用程序中处理连接的讨论可在此处找到。
因为Heroku没有提供超级用户访问权限,所以您的选择相当有限。

如果我没有表达清楚,对不起。泄漏的连接似乎来自本地程序(Navicat)。我关闭了该程序,重新启动了我的笔记本电脑,重启了路由器,并手动终止了所有具有打开连接的进程。因此,我认为我无法再做更多来减少从我的端口的连接数。我也多次在Heroku服务器上重新启动了我的应用程序。 - Jasper Schulte
很遗憾,就只有这些了。如果这是一个持续的问题,升级到付费计划可能是值得的。 - Robert H

7

重启服务器

heroku restart --app <app_name>

它将关闭所有连接并重新启动。

2

作为超级用户(例如“postgres”),您可以使用以下查询终止除当前会话外的所有会话:

select pg_cancel_backend(pid)
from pg_stat_activity
where pid <> pg_backend_pid();

如果它们不消失,您可能需要使用更强的“kill”,但首先一定要使用pg_cancel_backend()进行测试。
select pg_terminate_backend(pid)
from pg_stat_activity
where pid <> pg_backend_pid();

根据Heroku文档链接,作为超级用户您无法执行任何操作:Heroku Postgres用户在其数据库上被授予所有非超级用户权限。 - Jasper Schulte
你可能能够发出与数据库所有者相同的命令,你可以尝试一下看看是否适用于你。否则,除了在Heroku中可能或可能无法执行的弹跳数据库之外,我想不到其他任何事情了。 - bma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接