应优先设置 wait_timeout,interactive_timeout 可同步设为相同值;二者需在 [mysqld] 段落中以纯数字配置并重启 mysql,且需与连接池空闲超时协同调整。

wait_timeout 和 interactive_timeout 到底该设哪个
MySQL 的连接空闲超时由两个参数控制,不是二选一,而是按连接类型自动生效:wait_timeout 用于普通非交互式连接(比如应用通过 JDBC、PDO 建立的长连接),interactive_timeout 用于设置了 CLIENT_INTERACTIVE 标志的连接(如 MySQL CLI 登录后默认启用)。应用层几乎从不主动设这个标志,所以绝大多数 Web 服务实际生效的是 wait_timeout。
常见错误是只改了 interactive_timeout,结果应用连接还是被秒断——因为压根没走这条路。
- 查当前值:
SHOW VARIABLES LIKE '%timeout%'; - 修改建议:优先调
wait_timeout,interactive_timeout可同步设为相同值,避免混淆 - 注意:这两个是会话级变量,
SET wait_timeout = 60;只影响当前连接;持久化必须写进配置文件
my.cnf 里怎么写才真正生效
在 /etc/my.cnf 或 /etc/mysql/my.cnf 的 [mysqld] 段落下写,不是 [client] 或 [mysql]。写错位置等于没写。
示例正确写法:
[mysqld] wait_timeout = 60 interactive_timeout = 60
- 单位是秒,不能写
60s或1m,只认纯数字 - 改完必须重启 MySQL 进程(
systemctl restart mysql),FLUSH PRIVILEGES不管用 - 如果用 Docker,确保挂载的是最终生效的配置文件,别被镜像内默认配置覆盖
应用端还连不上?检查连接池是否绕过了 MySQL 超时
很多连接池(如 HikariCP、Druid)自己维护空闲连接,并主动做保活或驱逐。这时候 MySQL 层面的 wait_timeout 可能根本没机会触发——连接在到达 MySQL 超时前,就被池子干掉了。
典型表现:日志里看不到 MySQL server has gone away,但连接频繁重建。
- 确认连接池的
idleTimeout(HikariCP)或minEvictableIdleTimeMillis(Druid)是否小于 MySQL 的wait_timeout - 如果池子设了 30 秒空闲驱逐,MySQL 却设了 60 秒,那永远等不到 MySQL 断连,但池子可能因网络抖动误判
- 建议:池子的空闲超时比 MySQL 小 5–10 秒,留出检测和清理缓冲
超时断连后为什么报错不是 timeout 而是 “Lost connection”
MySQL 在连接被服务端强制关闭时,不会返回标准的 timeout 错误码,而是抛出类似 Lost connection to MySQL server during query 或 MySQL server has gone away 的提示。这不是客户端网络问题,是服务端主动踢人了。
- 这类报错大概率对应
wait_timeout触发,可查 MySQL 错误日志确认是否含Aborted connection -
connect_timeout控制的是“建立连接阶段”的超时,和这里无关;它默认 10 秒,一般不用动 - 如果应用日志里大量出现该错误且时间规律(比如整点后 60 秒集中爆发),基本就是
wait_timeout在起作用
真正麻烦的是那些没暴露在日志里的静默失效:连接池以为连接还活着,MySQL 却已关闭,下一次 query 才暴露。这种场景下,光调服务端参数不够,得配合连接池的 validationQuery 或 testOnBorrow 做有效性检测。











