Python MySQL connector超时关闭连接后服务端查询仍运行的解决方案咨询
问题解决方法
你遇到的问题本质是interruptingcow的超时逻辑仅终止了Python本地的代码执行,没有向MySQL服务端发送查询终止指令,因此关闭客户端连接并不会主动中断服务端已经开始执行的SQL,查询会一直运行到自然结束。
方案1:复用连接,超时后主动终止单条查询(推荐)
该方案不需要反复重建连接,性能更好,实现逻辑如下:
- 每次新建连接后先查询并保存当前连接的
CONNECTION_ID(),这是该连接在MySQL服务端的唯一标识 - 超时触发时,通过临时连接执行
KILL QUERY 连接ID终止当前查询,原连接可直接复用无需重建
修改后可运行的代码示例:
from interruptingcow import timeout import mysql.connector # 替换为你的数据库配置 config = { "user": "your_username", "password": "your_password", "host": "your_host", "database": "your_db", "raise_on_warnings": True } # 初始化主连接 cnx = mysql.connector.connect(**config) cursor = cnx.cursor() # 保存当前连接的服务端ID cursor.execute("SELECT CONNECTION_ID()") current_conn_id = cursor.fetchone()[0] for email in emails: query = journey_query.format(email=email) try: with timeout(10, exception=RuntimeError): results = cursor.execute(query, multi=True) for result in results: if result.with_rows: abc = result.fetchall()[0] else: continue except RuntimeError: # 新建临时连接终止当前查询 temp_cnx = mysql.connector.connect(**config) temp_cursor = temp_cnx.cursor() temp_cursor.execute(f"KILL QUERY {current_conn_id}") temp_cursor.close() temp_cnx.close() # 重置cursor残留状态即可继续复用 cursor.reset() continue cursor.close() cnx.close()
方案2:重连前批量清理所有当前账号下的运行中查询
如果不需要复用连接,每次重连前可以先批量杀死当前数据库账号下所有正在运行的查询:
- 执行
SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = '你的数据库用户名'获取所有当前账号的运行中连接ID - 批量执行
KILL QUERY ID清理所有查询
批量清理代码片段:
# 重连前先执行批量清理 temp_cnx = mysql.connector.connect(**config) temp_cursor = temp_cnx.cursor() # 可补充HOST过滤条件避免误杀其他机器的同账号连接,比如加AND HOST LIKE '192.168.1.100%' temp_cursor.execute("SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = %s", (config['user'],)) kill_ids = [row[0] for row in temp_cursor.fetchall()] for kill_id in kill_ids: temp_cursor.execute(f"KILL QUERY {kill_id}") temp_cursor.close() temp_cnx.close() # 后续再执行新建连接的逻辑 cnx = mysql.connector.connect(**config) cursor = cnx.cursor()
注意事项
KILL QUERY仅终止连接上的运行中查询,不会断开连接;如果需要完全终止连接,可以用KILL CONNECTION- 批量清理时如果有其他业务也用同一个数据库账号,建议增加HOST过滤条件,避免误杀其他业务的查询
- 非必要场景建议避免使用
multi=True执行多语句,会大幅增加查询状态管理的复杂度,建议拆分为单条语句执行
内容的提问来源于stack exchange,提问作者Thomas Reynaud
相关产品推荐
相关产品推荐

