我使用pymysql连接mysql,并在连接时设置一个read_timeout:
conn = pymysql.connect(host=host,port=port,user=user,passwd=passwd,read_timeout=60)我的查询代码在这里:
try:
cur.execute(sql)
rows = cur.fetchall()
except:
# timeout
logging.error()
finally:
cur.close()
conn.close()当我执行长时间查询时,代码会引发超时错误,最后cursor和connection都已关闭(我调试conn._closed以确认连接已关闭).But,当我登录到mysql和show processlist时,我发现进程仍然处于活动状态。
我的问题是,这是否正常,在我的代码中查询超时时,我如何才能终止这个进程?我想出了一个在查询前执行set session max_execution_time=60的解决办法,但我认为这不是最佳实践。
这里是show processlist输出,我使用sleep来表示长时间的查询,我认为结果是一样的,connection在我的代码中是封闭的,但是进程仍然存在。
发布于 2019-05-06 14:08:57
read_timeout on PyMySQL连接对象在读取操作期间用作底层插座上的超时值。如果到达超时,套接字将引发OSError (socket.timeout)子类,该子类将在连接的字节数方法中捕获。
在处理该异常期间,将执行关,这将最终设置到None的连接的self._sock属性。
当您的代码到达finally块时,在执行conn.close()期间所要做的就是将_closed设置为True。
如果此时_sock不是None,close方法也会尝试通过套接字将COM_QUIT发送到服务器,但是由于客户端套接字已经关闭,所以不会发生这种情况。
从服务器的角度来看,客户端不加言语地放弃了连接。不幸的是,很难找到关于在这种情况下到底发生了什么的有意义的文档。
通常,在连接超时时,应回滚挂起的事务。但是,我不确定客户端关闭其套接字是否会导致服务器端立即超时,正如这个问答中所建议的那样。
此外,使用MySQL的sleep函数进行测试可能是个坏主意。它可以完全挂起处理连接和查询的线程,使其无法及时检测丢失的连接。
您可能想看看MySQL的杀掉命令,这个命令也是在PyMySQL 连接中实现的,尽管没有文档说明。但是,当使用可能需要很长时间才能完成的语句执行cursor.execute时,这将需要在脚本中进行外部超时。
https://stackoverflow.com/questions/56002258
复制相似问题