根源在于wait_timeout和interactive_timeout配置,必须查SHOW GLOBAL VARIABLES确认;云数据库需改配置文件并重启,且须同步调优连接池与网络中间件超时。

MySQL 存储过程执行中途报 Communications link failure,大概率不是存储过程本身的问题,而是连接在执行过程中被服务端主动断开了——根源几乎总落在 wait_timeout 和 interactive_timeout 配置上。
查当前生效的 timeout 值必须用 SHOW GLOBAL VARIABLES
很多人连上 MySQL 后执行 SHOW VARIABLES LIKE 'wait_timeout',看到值没变就以为改失败了。其实这是查的会话级变量,而连接空闲超时由全局值决定。真正要确认服务端行为,必须运行:
SHOW GLOBAL VARIABLES LIKE 'wait_timeout';<br>SHOW GLOBAL VARIABLES LIKE 'interactive_timeout';
注意两点:
-
wait_timeout控制 JDBC、ORM 等非交互式连接;interactive_timeout控制mysql命令行这类交互式连接 - 如果两个值不一致,新连接的会话
wait_timeout会继承自对应客户端类型所匹配的那个全局值(JDBC 默认走wait_timeout路径) - 某些连接池(如早期 Druid)会显式声明
CLIENT_INTERACTIVE,这时实际受interactive_timeout约束——所以两个都得查、都得调
SET GLOBAL 修改后仍不生效?可能是重启前被覆盖了
执行 SET GLOBAL wait_timeout = 3600 看似成功,但下次 MySQL 重启后立刻回滚。原因很实在:
- MySQL 启动时只读一次配置文件(
/etc/my.cnf或my.ini),之后全局变量就固化了 - 若配置文件里没写
wait_timeout,它才用编译默认值(28800);一旦你SET GLOBAL,只是内存里改了,没落盘 - 更隐蔽的是:某些云数据库(如阿里云 RDS、腾讯云 CDB)根本不允许
SET GLOBAL,连执行都报错
所以生产环境别依赖临时 SET,直接改配置文件,在 [mysqld] 段落下加:
wait_timeout = 3600<br>interactive_timeout = 3600
然后完整重启 mysqld 进程(systemctl restart mysql),不是 reload。
存储过程执行时间长,光调大 timeout 不够
假设你的存储过程要跑 2 小时,把 wait_timeout 设成 7200 秒(2 小时)看似够用,但仍有风险:
- MySQL 的空闲计时器从“最后一条语句执行完”开始算,不是从存储过程启动时算。如果过程里有大循环、
SLEEP()、或长时间等待锁,中间任何一段空闲都会计入 timeout - 连接池可能比数据库更早“放弃”这个连接。例如 HikariCP 的
max-lifetime默认是 1800000ms(30 分钟),哪怕数据库设了 2 小时,连接池也会在 30 分钟后主动销毁连接 - 网络中间件(如 SLB、NAT 网关)常自带 5~15 分钟的连接空闲超时,它比 MySQL 先掐断连接,且不通知两端
所以真实场景下,必须同时检查三层:
- MySQL 层:
wait_timeout/interactive_timeout - 连接池层:
max-lifetime、idle-timeout、validation-query(如SELECT 1) - 基础设施层:负载均衡器、防火墙、云厂商 NAT 超时设置
别碰 autoReconnect=true,它在 MySQL 5.5+ 已失效
很多老教程还教你在 JDBC URL 里加 autoReconnect=true,这在当前所有主流版本(5.7/8.0)中都不起作用:
- 驱动不再静默重连,而是直接抛
CommunicationsException,和不加一样 - 它可能掩盖事务断裂问题:前一条 UPDATE 已提交,重连后下一条 INSERT 在新会话执行,逻辑一致性全毁
- 官方文档明确标注为 deprecated,部分新版驱动甚至解析都报 warning
真要容错,靠连接池的健康检测(testOnBorrow + validationQuery)或应用层心跳(定时 SELECT 1),而不是寄希望于这个参数。
最易被忽略的一点:wait_timeout 是连接建立时“快照”下来的值,后续即使你动态改了全局配置,已存在的连接不会刷新这个值。这意味着,哪怕你刚改完配置并重启了 MySQL,旧连接依然按原来的 timeout 计时——所以排查时一定要确认出问题的连接是新建立的,还是复用的老连接。


















