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


99

我将Heroku与Crane Postgres选项一起使用,当本地计算机崩溃时,我正在从本地计算机上对数据库运行查询。如果我跑步

select * from pg_stat_activity

其中一项具有

<IDLE> in transaction

在current_query_text列中。

结果,我无法删除已终止查询所写入的表。我试过使用pg_cancel_backend(N),它返回True,但似乎什么也没有发生。

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


1
也许这个问题应该改写为“在既没有root访问postgres服务器也没有超级用户访问数据库的情况下,如何终止我自己的查询”。看来这确实是一个很好的问题……我不知道答案。
tobixen 2012年

Answers:


138

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


(对这个问题的简单愚蠢的答案可能是……只是重新启动postgresql。假设这是不希望的或不是一个选择……)

通过运行以下sql查找PID:

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

(查询可能需要根据postgres的版本进行修改-最终,只需从pg_stat_activity中选择*)。您会在第一列(左)中找到该pid,而第一列(顶部)很可能是您要终止的查询。我假设pid是下面的1234。

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

select pg_cancel_backend(1234);

这是取消1234查询的“友好”请求,幸运的是,它会在一段时间后消失。最终,这会更有效:

select pg_terminate_backend(1234);

如果您具有外壳程序访问权限以及root或postgres权限,则也可以从外壳程序执行此操作。要“取消”,可以执行以下操作:

kill -INT 1234

并“终止”,只需:

kill 1234

不要:

kill -9 1234

...这通常会导致整个postgres服务器瘫痪,那么您最好重启postgres。Postgres非常强大,因此数据不会被破坏,但是无论如何我建议不要使用“ kill -9” :-)


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


我尝试pg_cancel_backend无济于事。我没有外壳程序访问权限,而且我不是超级用户,所以我无法使用pg_terminate_backend发送SIGKILL
alan

您正在使用哪个版本的postgres?(提示:)select version()。使用时是否收到任何错误消息pg_cancel_backend
tobixen 2012年

尝试自己使用pg_cancel_backend,因此收到错误消息“必须是超级用户才能向其他服务器进程发出信号”……这意味着您显然需要通过某些postgres超级用户(即postgres用户)对服务器进行root访问或db访问)杀死自己的查询。似乎有点烂:-(
tobixen

1
原来,进程已被pg_cancel_backend取消了,但查询仍然在pg_stat_activity中显示了一段时间
alan

也许它特定于Heroku。据我所知,在普通的postgres下,确实需要超级用户才能杀死卡住的进程(我在pg 8.4上用“ select pg_sleep(3600);”进行测试,我得到“ ERROR:必须是超级用户才能发出信号其他服务器进程”)。不过,那么“闲置的交易”还是不太一样。
tobixen 2012年

36

试试这个:

select pg_terminate_backend(pid int)

有关此的更多信息,请参见此处。这应该比通过系统终止进程来解决此问题更“干净”。


请新增如何让你的PID到你的答案
mountainclimber

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


谢谢。我仍然无法终止事务/ PID。。。我的计算机在导入过程中发生硬件冻结,无法终止PID。:(
dimitarvp

-3

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

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

那会杀死所有正在运行的查询,那么不妨重新启动postgres。按照xact_start并限制为1的顺序排序,我可以同意……但话又说回来,我宁愿在盲目杀死之前先查看列表。
tobixen

那这个呢?SELECT pid, pg_cancel_backend(pid) FROM pg_stat_activity WHERE state != 'idle' AND (now() - query_start) > interval '5 minutes';
AFN
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.