wait_timeout是MySQL服务端断开空闲连接的时限(单位秒),影响非交互式连接(如应用直连);超时后连接被强制关闭,导致“MySQL server has gone away”错误。

wait_timeout 是什么,改它到底影响谁
wait_timeout 控制的是 MySQL 服务端对「空闲连接」的断开时限。不是查询超时,也不是事务超时,而是客户端连上来之后啥也不干、光挂着的时间上限。一旦超过这个秒数,MySQL 主动踢掉连接,下次再发请求就会报 MySQL server has gone away。
常见踩坑场景:长周期脚本(比如 Python 的 while True 循环里复用一个连接)、连接池配置不合理、Web 应用里手动管理连接但没及时关闭。
注意:wait_timeout 和 interactive_timeout 是两个独立参数,前者作用于非交互式连接(比如应用直连),后者作用于交互式连接(比如你敲 mysql -u root -p 进去的命令行)。大多数应用走的是前者。
怎么改 wait_timeout:会话级 vs 全局级
临时改当前连接有效(不推荐用于生产):
SET SESSION wait_timeout = 28800;
永久生效必须改配置文件或启动参数,否则重启就还原。在 my.cnf 或 my.ini 的 [mysqld] 段下加:
wait_timeout = 28800
然后重启 MySQL(systemctl restart mysqld 或对应服务名)。别只改 SET GLOBAL —— 它虽然能生效,但 MySQL 重启后丢失,且某些版本(如 5.7+)要求同时设 interactive_timeout 才真正稳定。
- 修改后必须重启 MySQL,
SET GLOBAL不足以让已有连接继承新值 - 如果用的是云数据库(如阿里云 RDS、腾讯云 CDB),通常不开放配置文件修改,得走控制台参数模板或工单申请
- 单位是秒,28800 = 8 小时;设太大(比如 31536000)容易积累僵尸连接,压垮连接数限制
应用端配合比单纯调大 wait_timeout 更关键
光调服务器参数治标不治本。很多问题其实是应用没正确处理连接生命周期导致的。
典型错误现象:Lost connection to MySQL server during query 或连接突然中断后重试失败。
建议动作:
- 确认连接池是否启用了「心跳检测」或「连接有效性验证」(如 HikariCP 的
connection-test-query或validation-timeout) - 避免在业务逻辑里长期持有连接对象(比如把
conn当全局变量用) - Python 的
pymysql/mysql-connector-python默认不自动重连,得显式开autocommit=True或捕获异常后重建连接 - Java 项目若用 Spring Boot,默认 HikariCP 的
max-lifetime建议设为比wait_timeout小 30–60 秒,避免连接被服务端先杀
查当前值和验证是否生效
别猜,直接查:
SHOW VARIABLES LIKE 'wait_timeout';
注意返回的是整数(单位秒),不是字符串。如果看到 28800,说明已加载;如果还是 28800 但应用仍报错,大概率是连接建立时间早于配置变更,或者应用用的是旧连接。
验证连接是否真被踢了,可以手动模拟:
SELECT SLEEP(30); -- 然后等 30 秒以上再发下一条语句,看是否报错
更准的方式是查当前活跃连接的空闲时间:
SELECT id, user, host, db, command, time, state FROM information_schema.processlist WHERE command = 'Sleep';
其中 time 列就是该连接空闲了多少秒 —— 对照你的 wait_timeout 值就能判断是否快被清理了。
改完别忘了检查 max_connections 是否够用,因为调大 wait_timeout 后,同样连接数下空闲连接堆积更多,更容易触发上限。










