首先,我运行此查询看到正在运行的查询:如何在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”中的内容将不会更新 –