首先,我運行此查詢看到正在運行的查詢:如何在PostqreSQL中停止正在運行的查詢?
select * from pg_stat_activity;
然後我運行此查詢阻止他們:
SELECT pg_cancel_backend(pid);
,但是,當我再次運行和pg_stat_activity,它仍然顯示所有查詢!
爲什麼它沒有殺死查詢?
首先,我運行此查詢看到正在運行的查詢:如何在PostqreSQL中停止正在運行的查詢?
select * from pg_stat_activity;
然後我運行此查詢阻止他們:
SELECT pg_cancel_backend(pid);
,但是,當我再次運行和pg_stat_activity,它仍然顯示所有查詢!
爲什麼它沒有殺死查詢?
一些可能的解釋:
你不是在看一個活動的查詢,查詢文本僅僅是在當前空閒背跑了過去查詢。在這種情況下,pg_cancel_backend
將不會執行任何操作,因爲沒有任何要取消的操作。檢查pg_stat_activity
中的state
字段。
正在執行的查詢在擴展代碼中運行,該代碼在執行任何操作期間都不是CHECK_FOR_INTERRUPTS()
。這是最典型的情況,當你運行一些擴展時,使用它自己的庫,套接字等來執行大量的CPU,I/O或網絡活動。特別是諸如PL/Perl,PL/Python等。
活動查詢在PostgreSQL後端代碼中運行,該代碼不檢查長時間運行循環或類似情況下的中斷。這是一個錯誤;如果你發現這種情況,請報告。
後端卡住等待阻塞操作系統調用,通常是磁盤I/O或網絡套接字寫入。它可能無法響應取消消息,直到阻止操作結束,但如果它收到一個SIGTERM
它的信號處理程序通常可以讓它救市,但並非總是如此。
通常使用pg_terminate_backend
作爲「更大的錘子」是安全的。由pg_terminate_backend()
發送的SIGTERM
經常(但並非總是)會導致後端無法響應取消退出。
待辦事項不kill -9
(SIGKILL
)PostgreSQL的後端(postgres
過程)。它會導致整個PostgreSQL服務器緊急重啓以保護共享內存的安全。
我經常遇到另一個陷阱:我通常使用autocommit turneed ** off **運行,只有當我結束該事務時,「pg_stat_activity」纔會更新。似乎對「pg_stat_activity」的訪問總是通過「可重複讀」隔離級別完成的 –
@a_horse_with_no_name請參閱http://stackoverflow.com/q/41421429/398670 –
我應該使用pg_terminate_backend(pid)而不是pg_cancel_backend(pid)。
如果這很簡單,我們就不會爲「pg_cancel_backend」而煩惱。 –
當會話或請求不再存在時,[Stop(long)running PostgreSQL中的SQL查詢可能重複?](http://stackoverflow.com/questions/3508627/stop-long-running-sql-query-in- postgresql-when-session-or-requests-no-longer-e) –
你關閉了自動提交嗎?在這種情況下,除非您終止您的交易,否則「pg_stat_activity」中的內容將不會更新 –