如何用JDBC取消PostgreSQL中长时间运行的查询?

时间:2015-07-11 15:58:14

标签: java postgresql

在我的项目中,我有一些遗留插件。这些插件用于PostgreSQL的只读查询。大多数插件运行良好,但其他部分非常慢。这是因为从C3P0获取连接而导致挂断的原因。 它看起来像池上连接超时的更改没有效果。

如何设置超时以有效取消这些查询? 我认为服务器端的超时可能是很好的解决方案,但我不想在配置中为所有服务器设置超时。此外,我不想删除此连接,只需取消当前查询。

您能否分享一下有关此问题的解决方案的想法?

2 个答案:

答案 0 :(得分:3)

如果动态设置配置参数statement_timeout,则此参数仅影响当前会话: 在不丢弃连接的情况下,将取消执行超过给定时间的查询。

test=# set statement_timeout to 1000;  -- 1s
SET
test=# select pg_sleep(5);             -- 5s
ERROR:  canceling statement due to statement timeout
test=# set statement_timeout to 0;     -- turn off
SET

更新 - 简要概述控制Postgres流程的方法。

您可以列出服务器的所有正在运行的进程:

test=# select pid, query_start, state, query from pg_stat_activity;
 pid  |        query_start         | state  |                            query
------+----------------------------+--------+--------------------------------------------------------------
 4004 | 2015-07-12 20:50:01.033+02 | active | select pid, query_start, state, query from pg_stat_activity;

例如,此查询列出了执行时间超过5分钟的查询:

select *
from pg_stat_activity
where state = 'active'
and now() - query_start > '5m';

您可以手动取消长时间运行的查询:

select pg_cancel_backend(pid);

或终止流程:

select pg_terminate_backend(pid);

您可以运行程序,该程序会自动取消长时间运行的查询。 它可能是后台流程(daemon),也可能是cron执行。

此查询会自动取消执行时间超过5分钟的查询:

select pg_cancel_backend(pid)
from pg_stat_activity
where state = 'active'
and now() - query_start > '5m';

当然,这种自动化解决方案必须以非常谨慎的方式实施,并充分了解后果。

文档中的更多内容:pg_stat_activitypg_cancel_backend()

答案 1 :(得分:2)

经过@klin对postgres行为的一些研究和提示后,我解决了我的问题。 c3p0连接池用于旧版插件。我已经找到了为池行为添加自定义扩展的能力。

http://www.mchange.com/projects/c3p0/#user_extensions_to_configurations

默认情况下,c3p0中提供了initSql扩展名。这样我们就可以把命令

  

将statement_timeout设置为1000;

在您的配置文件中,它将在您的源代码中没有任何更改的情况下运行。只需重建你的插件jar就可以了!