如果连接丢失/断开,Postgres长期运行的查询是否会中止?


20

如果我打开与Postgres的连接并发出长时间运行的查询,然后中断连接(例如,杀死打开该连接的客户端进程),那么长时间运行的查询会继续运行,还是会自动中止?这是可配置的吗?

(我正在使用Postgresql 9.2.9)

Answers:


32

“这取决于”。

如果客户端由于网络连接丢失而消失,则查询通常将一直运行,直到检索到足够的行以填充其网络发送缓冲区为止,然后停止并卡住,直到TCP连接断开,此时它将终止。如果填充TCP发送缓冲区之前完成它将成功完成,因此如果是自动提交,则查询将提交。

如果以某种方式杀死客户端,使得客户端的操作系统可以通过TCP RST向服务器报告(例如客户端段错误/崩溃,SIGTERM,SIGKILL等),则PostgreSQL服务器将设置中断标志。下次查询在执行时检查中断时,它将看到该标志并中止。有时查询可能在不检查中断的代码中执行大量的CPU工作-某些扩展名以及PostgreSQL内核中的一些位置-在这种情况下,它可能很长一段时间都不会注意到中断并继续运行。但是,如果它是自动提交的,它将几乎总是在完成和提交之前看到中断并中止。

如果客户端由于突然的操作系统重启而被杀死,因此客户端主机突然对TCP连接一无所知,但仍然可以在网络上进行响应,则该查询可能在第一次尝试写行时就被中止。杰夫说,因为客户端的主机将在重新启动后响应服务器发送的第一个数据包发送TCP RST。PostgreSQL在发送的每一行检查中断。

这种行为是不可配置的。就PostgreSQL而言,如果客户端消失了,它的工作就是终止客户端正在运行的所有查询。要进行更改,您需要某种可以在查询开始时获得的查询完成令牌,然后用于稍后通过另一个连接向服务器询问查询。本质上,您必须实现异步/后台查询。可能是一个不错的功能,但当前不支持。

如果查询是自动提交的,或者查询是在终止COMMIT客户端/断开连接时正在进行的查询,则事务可能处于不确定状态,此时客户端不知道或不知道不是承诺。除了寻找交易对数据的影响外,没有真正的方法可以找出答案。

在无法接受的地方,可以使用两阶段提交和一个客户端事务管理器。


1
哇,正是我想要的,一个很好的详细答案!谢谢@Craig_Ringer!
Rob Bednark 2014年


2

它将继续运行,直到尝试将行返回到连接并检测到损坏。因此,对于在返回任何行之前完成所有工作的查询,它实际上将运行到完成。


谢谢@jjanes。您可以指出任何表明这一点的文档或源代码吗?
罗伯·贝德纳克(Rod Bednark)2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.