Heroku Postgres - 终止挂起查询(在事务中空闲)

时间:2012-07-02 10:00:59

标签: postgresql heroku

我正在使用Heroku和Crane Postgres选项,当我的本地计算机崩溃时,我正在本地计算机上运行数据库查询。如果我跑

select * from pg_stat_activity

其中一个条目

<IDLE> in transaction
<_>在current_query_text列中。

因此,我无法删除被终止的查询写入的表。我尝试过使用pg_cancel_backend(N)并返回True但似乎没有任何事情发生。

如何终止此过程以便我可以删除该表?

4 个答案:

答案 0 :(得分:117)

这是Postgres的一般答案,并非特定于heroku


(对这个问题的简单愚蠢的回答可能是......只需重启postgresql。假设这不可取或不是一个选项......)

通过运行此sql来查找PID:

SELECT pid , query, * from pg_stat_activity
  WHERE state != 'idle' ORDER BY xact_start;

(Postgres的旧版本使用procpid而不是pid)。您将在第一个(左侧)列中找到pid,第一个(顶部)行可能是您要终止的查询。我假设pid是1234以下。

您可以通过SQL取消查询(即没有shell访问权限),只要它是您的,或者您拥有超级用户访问权限:

select pg_cancel_backend(1234);

这是“软”方式......查询不会立即消失。如果这不起作用,请改用:

select pg_terminate_backend(1234);

如果你有shell访问权限以及root或postgres权限,你也可以从shell中执行:

kill -INT 1234

如果这没有帮助,请使用:

kill 1234

请勿:

kill -9 1234

...这通常会导致整个postgres服务器火上浇油,然后你也可以重新启动postgres。 Postgres非常强大,所以数据不会被破坏,但我建议不要在任何情况下使用“kill -9”: - )


持久的“事务中空闲”通常意味着事务没有以“提交”或“回滚”终止,这意味着应用程序存在错误或未正确设计以使用事务数据库。应该避免持久的“交易闲置”,因为它也会导致严重的性能问题。

答案 1 :(得分:36)

试试这个:

select pg_terminate_backend(pid int)

有关此内容的更多信息,您可以找到here。这应该是解决这个问题的“更清洁”,而不是系统杀死过程。

答案 2 :(得分:19)

您可以安装heroku-pg-extras加载项并运行以下命令来获取PID:

heroku pg:locks --app <your-app>

然后就这样做:

heroku pg:kill <pid> --app <your-app> 

注意--force选项可用于发出pg_terminate_backend,从而删除该查询的整个连接。

如果heroku pg:locks未列出任何内容,请尝试heroku pg:ps

有关详细信息,请查看:
https://devcenter.heroku.com/articles/heroku-postgresql#pg-ps-pg-kill-pg-killall

答案 3 :(得分:0)

我们可以使用以下内容在单个查询中实现:

SELECT pg_cancel_backend(pid), pg_terminate_backend(pid) FROM pg_stat_activity WHERE state != 'idle';