在我的項目中,我有一些傳統的插件。這些插件用於PostgreSQL的只讀查詢。大多數插件運行良好,但其他部分非常慢。這是停止從C3P0獲取連接的原因。 它看起來像連接超時的更改沒有效果。如何用JDBC取消PostgreSQL中長時間運行的查詢?
如何設置有效取消這些查詢的超時時間? 我認爲服務器端的超時可以是很好的解決方案,但我不想在配置中爲所有服務器設置超時。另外我不想丟棄這個連接,只需要取消當前查詢。
你能分享你對這個問題的解決方案的想法嗎?
在我的項目中,我有一些傳統的插件。這些插件用於PostgreSQL的只讀查詢。大多數插件運行良好,但其他部分非常慢。這是停止從C3P0獲取連接的原因。 它看起來像連接超時的更改沒有效果。如何用JDBC取消PostgreSQL中長時間運行的查詢?
如何設置有效取消這些查詢的超時時間? 我認爲服務器端的超時可以是很好的解決方案,但我不想在配置中爲所有服務器設置超時。另外我不想丟棄這個連接,只需要取消當前查詢。
你能分享你對這個問題的解決方案的想法嗎?
如果您動態設置配置參數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';
當然,這種自動化解決方案必須非常謹慎和與後果充分認識實施。
經過對@glin的postgres行爲的一些研究和暗示,我已經解決了我的問題。 c3p0連接池用於傳統插件。我已經找到了將自定義擴展添加到池行爲的功能。
http://www.mchange.com/projects/c3p0/#user_extensions_to_configurations
有默認的C3P0提供initSql擴展。這樣我們可以把命令
設置statement_timeout爲1000;
在您的配置文件中,它將在您的源代碼沒有任何改變的情況下工作。所有你需要的只是重建你的插件jar!
來自不同線程的Statement.cancel()'對我來說工作正常。 –