必须同步设置wait_timeout和interactive_timeout为相同值(如300秒),并匹配连接池maxlifetime等参数,否则mysql服务端断连而连接池仍分发失效连接,导致“mysql server has gone away”等错误。

只改 MySQL 的 wait_timeout 会失效,必须同步调整 interactive_timeout 和连接池参数,否则应用照样报 “Communications link failure”。
为什么改了 wait_timeout 还连不上
常见现象是低峰后第一次请求失败,报 MySQL server has gone away 或 Lost connection to MySQL server during query。这不是网络问题,而是 MySQL 已在后台关闭空闲连接,但连接池仍把它当“活连接”分发给业务代码。
-
wait_timeout默认 28800 秒(8 小时),远大于 HikariCP 默认的maxLifetime=1800000(30 分钟) - 连接池没感知到服务端已断连,下次取连接就直接炸
-
SET GLOBAL只影响新建立的连接,旧连接继续按老值计时,不会立即断开
wait_timeout 和 interactive_timeout 必须设成一样
哪怕你不用命令行,也得一起调——某些驱动(如 PyMySQL 旧版)会误设 CLIENT_INTERACTIVE 标志,导致实际走的是 interactive_timeout 路径。
- 生产建议统一设为
300(5 分钟)或600(10 分钟):300适合高并发短事务;600更稳妥,兼容长轮询或延迟提交场景 - 临时验证:运行
SET GLOBAL wait_timeout = 300;和SET GLOBAL interactive_timeout = 300; - 永久生效:在
/etc/my.cnf的[mysqld]段加两行:wait_timeout = 300和interactive_timeout = 300 - Linux 下最小合法值是
1,设0无效;Docker 环境需docker restart mysql才生效
HikariCP / Druid 必须比 MySQL 更早清理连接
连接池的清理阈值必须略小于 MySQL 的 wait_timeout,留出缓冲时间,否则还是抢不过服务端断连节奏。
- HikariCP:
maxLifetime设为290000(对应wait_timeout=300),idleTimeout设为280000,并启用connection-test-query=SELECT 1(MySQL 8.0.22+ 推荐用connection-init-sql=SELECT 1) - Druid:
testWhileIdle=true,timeBetweenEvictionRunsMillis=25000(25 秒检测一次),minEvictableIdleTimeMillis=280000 - PyMySQL/MySQLdb 客户端:确保每次取连接前调用
ping(True),或设autocommit=True避免事务卡住连接
connect_timeout 不是空闲超时,别混用
connect_timeout 控制 TCP 握手 + 认证阶段的等待上限,和空闲断连无关。它防的是半开连接攻击(比如 SYN flood 或卡在密码校验),不是连接用久了被踢。
- 默认值
10秒通常够用;若用了 PAM/LDAP 认证或链路极差,可临时提到15,但绝不能超过30 - 该参数无法
SET GLOBAL动态修改,必须写进配置文件并重启 MySQL - 配合
max_connect_errors=3使用(需开启skip-name-resolve),连续失败三次即封 IP
真正容易被忽略的,是“谁在用哪个值”:命令行登录走 interactive_timeout,JDBC 默认走 wait_timeout,但某些 ORM 会悄悄加标志切换路径;改完参数后旧连接不立即退出,得等它们自然空闲超时或重启连接池才能彻底清理干净。











