MySQL空闲连接断开由wait_timeout(非交互式,如JDBC)和interactive_timeout(交互式,如mysql命令行)共同控制;5.7+默认按非交互式处理,故应用主要受wait_timeout影响,需同步调小该值并匹配连接池配置,避免“MySQL server has gone away”错误。

wait_timeout 和 interactive_timeout 是 MySQL 服务端控制空闲连接断开的两个核心参数,不是客户端能单方面决定的。绝大多数应用(JDBC、ORM、连接池)走的是 wait_timeout,而不是 interactive_timeout。
为什么改了 interactive_timeout 却没效果?
因为你的应用连接默认是非交互式的——除非显式声明 CLIENT_INTERACTIVE 标志(比如 JDBC URL 加 &interactiveClient=true,或命令行用 mysql --interactive)。MySQL 5.7+ 默认把所有新连接当非交互式处理,所以 interactive_timeout 实际只影响你手动敲 mysql -u root -p 这类会话。
常见误判:看到连接断开,就以为是 interactive_timeout 生效,结果发现应用根本没走它。
wait_timeout 怎么设才合理?
默认值 28800(8 小时)对生产环境太长,容易堆积大量空闲连接,拖慢 SHOW PROCESSLIST、触发连接数上限或掩盖连接泄漏问题。
推荐设为 300(5 分钟),同时必须同步调整应用层连接池的配置:
• HikariCP 的 connection-timeout 要小于 wait_timeout(比如设为 30000)
• Druid 的 minIdle 和 maxActive 需配合健康检查周期(如 validationQuery + testWhileIdle)
• 不要只改服务端却不配连接池,否则连接池可能在 MySQL 已断开后还继续复用“假连接”,报 Communications link failure
临时改 vs 永久生效,哪个更危险?
SET GLOBAL wait_timeout = 300 立即生效,但仅对之后新建的连接起作用,已有连接仍按旧值计时;重启 MySQL 后失效。
写进 my.cnf 的 [mysqld] 段:wait_timeout = 300interactive_timeout = 300
重启后才生效,但能避免重启前被误调大导致连接堆积。
风险点:
• SET GLOBAL 权限需 SUPER 或 SYSTEM_VARIABLES_ADMIN,普通应用账号做不到
• 直接改配置文件后忘记重启,以为生效了,其实没变
• 两个参数值不一致,会导致同一批连接里部分走一个超时逻辑,排查时行为割裂
别漏掉 net_read_timeout 和 net_write_timeout
这两个参数管的是“正在传输数据时卡住”的场景,不是空闲等待。
比如大 BLOB 查询中途网络抖动、慢日志写入阻塞、主从复制延迟突增,都可能触发它们。
默认 net_read_timeout = 30、net_write_timeout = 60,对批量导入或长事务不够用。
若业务有导出百万行 CSV、执行大事务或跨机房同步,建议根据实际网络质量调高:
• SET GLOBAL net_read_timeout = 120
• SET GLOBAL net_write_timeout = 120
注意:它们不影响连接建立或空闲断开,只影响读/写操作挂起多久后放弃


















