Python脚本运行数小时后MySQL连接中断报错问题排查
问题根因
两个报错本质是长连接无保活、连接资源泄漏、进程托管方式错误三类问题叠加导致的,和网络本身的基础连通性无关:
- 定时器线程的MySQL连接资源泄漏:当前逻辑是每分钟、每小时触发任务时新建MySQL连接,但没有在任务结束后显式关闭连接,也没有做连接有效性校验。运行数小时后,一方面会占满系统预留的TCP临时端口,导致新连接无法发起,触发
101 Network is unreachable错误;另一方面残留的长期空闲连接会被路径上的防火墙、NAT网关回收(绝大多数企业网络设备默认会丢弃静默30~120分钟的无流量TCP会话),后续读写这些已被回收的死连接时,就会触发Software caused connection abort类的连接中止错误。 - PuTTY会话断连连带脚本进程退出:如果是通过PuTTY的SSH会话前台运行脚本,SSH连接本身如果长时间无有效流量,同样会被网络设备主动断开,弹出对应的PuTTY致命错误。默认情况下SSH会话断开时系统会给会话内所有前台进程发SIGHUP信号,直接终止脚本运行,后续的数据库操作自然全部失败。
- 缺少异常兜底逻辑:MySQL客户端没有配置自动重连,数据库操作也没有失败重试机制,单次连接因为网络波动断开后,后续所有任务都会直接抛错,不会自动恢复。
修复方案
按优先级从高到低落地即可:
- 修正MySQL连接逻辑
- 禁止每次定时任务触发时新建裸连接,改用
mysql.connector.pooling创建大小为2的连接池,两个定时任务共用同一个连接池,每次执行SQL从池内取连接,操作完成后自动归还。连接池会自动检测空闲连接有效性、回收超时死连接,从根源避免连接泄漏。 - 连接初始化时增加参数:
autocommit=True, connection_timeout=10,每次执行SQL前先调用conn.ping(reconnect=True, attempts=3, delay=2),强制检测连接状态,死连接自动重建。 - 给所有数据库操作加try-except捕获网络类异常,捕获到错误后等待3秒重试最多3次,避免单次网络波动直接把定时线程打挂。
- 禁止每次定时任务触发时新建裸连接,改用
- 解决PuTTY断连导致脚本退出的问题
- 不要依赖PuTTY前台会话跑长驻服务:Linux环境下用
nohup python3 production_counter.py > run.log 2>&1 &把脚本丢后台运行,或者配置systemd服务托管;Windows环境下用nssm把脚本注册成系统服务,实现开机自启、异常自动重启,完全脱离SSH/远程桌面会话运行。 - 如果必须通过PuTTY实时看输出,打开PuTTY配置-Connection选项,把
Seconds between keepalives (0 to turn off)值设为30,让PuTTY每30秒自动发SSH保活包,避免连接被网络设备回收。
- 不要依赖PuTTY前台会话跑长驻服务:Linux环境下用
- 可选稳定性优化
- 给脚本加本地文件日志,记录每次计数、数据库操作结果、报错时间和详情,方便排查偶发问题。
- 不要在定时任务里写死数据库IP直连,如果有内网DNS优先用域名解析,避免IP段临时调整导致的连接失败。
内容的提问来源于stack exchange,提问作者Astrid Dunning
相关产品推荐
相关产品推荐

