112

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

select * from pg_stat_activity

其中一项有

<IDLE> in transaction

在 current_query_text 列中。

结果,我无法删除已终止的查询正在写入的表。我尝试使用 pg_cancel_backend(N) 并返回 True 但似乎没有任何反应。

我怎样才能终止这个过程,以便我可以删除表?

4

3 回答 3

161

这是一个一般的 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);

如果您有 shell 访问权限和 root 或 postgres 权限,您也可以从 shell 执行此操作。要“取消”,可以这样做:

kill -INT 1234

并“终止”,简单地说:

kill 1234

不要:

kill -9 1234

...这通常会导致整个postgres服务器陷入困境,那么您不妨重新启动postgres。Postgres 非常健壮,因此数据不会被破坏,但我建议在任何情况下都不要使用“kill -9”:-)


长期的“事务空闲”通常意味着事务没有通过“提交”或“回滚”终止,这意味着应用程序存在错误或未正确设计为与事务数据库一起使用。应该避免长时间的“事务空闲”,因为它也可能导致严重的性能问题。

于 2012-07-02T10:46:33.650 回答
36

试试这个:

select pg_terminate_backend(pid int)

您可以在此处找到更多相关信息。这应该是比系统杀死进程更“干净”的解决方案。

于 2013-05-07T16:04:27.713 回答
20

您可以安装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

于 2013-10-02T23:44:02.093 回答