简体   繁体   中英

How to cancel long running query in PostgreSQL with JDBC?

In my project i have some legacy plugins. These plugins used for read only queries from PostgreSQL. Most of plugins works well, but other part is really slow. It's reason for hangups on acquiring connection from C3P0. It's looks like changes for connection timeout on pool has no effect.

How i can set timeout for effective cancelation these queries? I think timeout for server side can be nice solution but i don't want set timeouts for all server in configs. Also i don't want drop this connection and need cancel current query only.

Can you share your ideas about solution for this problem?

If you set configuration parameter statement_timeout dynamically, this parameter affects only the current session: An execution of a query longer than the given time will be canceled without dropping a connection.

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

Update - a brief overview of means to control Postgres processes.

You can list all running processes of a server:

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;

For example, this query lists queries, which execution time is longer than 5 minutes:

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

You can manually cancel a long running query:

select pg_cancel_backend(pid);

or terminate a process:

select pg_terminate_backend(pid);

You can run a program, which automatically cancels long running queries. It may be a background process (daemon) or may be executed with cron .

This query automatically cancels queries which execution time are longer than 5 minutes:

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

Of course, this kind of automated solutions must be implemented with great caution and with full awareness of the consequences.

More in the documentation: pg_stat_activity , pg_cancel_backend() .

after some research and hints about postgres behaviour by @klin, i have resolved my problem. c3p0 connection pool are used in legacy plugins. i have found ability for adding custom extensions to pools behaviour.

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

There are initSql extension provided in c3p0 by default. In this way we can put command

set statement_timeout to 1000;

in your configuration file and it will works without any changes in your source code. All you need after it that rebuild your plugins jar only!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM