绝大多数web应用应将wait_timeout设为300~600秒(5~10分钟),避免空闲连接堆积和“mysql server has gone away”错误;需同步配置连接池的健康检查(如hikaricp或druid),使其maxlifetime略小于wait_timeout,并启用验证机制确保连接有效性。

wait_timeout 该调多少才不踩坑
绝大多数 Web 应用连接 MySQL 都走 wait_timeout,不是 interactive_timeout。默认 28800 秒(8 小时)太长,容易导致连接池拿到已被服务端断开的“假活连接”,进而抛出 MySQL server has gone away 或 Lost connection to MySQL server during query。
建议设为 300~600 秒(5~10 分钟),既避免夜间空闲连接堆积,又留出足够缓冲时间应对低峰期请求间隔。
- 临时验证:执行
SET GLOBAL wait_timeout = 300;,只对新连接生效,不影响已有连接 - 永久生效:在
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf的[mysqld]段下添加wait_timeout = 300 - 改完必须重启 MySQL 或执行
RELOAD(部分版本不支持动态重载,以SHOW VARIABLES LIKE 'wait_timeout';实际查到的值为准)
connect_timeout 和 socketTimeout 别混淆
connect_timeout 是服务端参数,控制 TCP 握手 + 认证阶段的最大等待时间,默认 10 秒。它和客户端“连不上”直接相关,比如网络抖动、DNS 解析慢、认证延迟高时,调大它能减少 Connection refused 类报错。
而 socketTimeout(JDBC)、read_timeout(PyMySQL)是客户端参数,控制已建立连接上的读写操作超时,单位毫秒。它防的是查询卡住、大结果集传输慢等场景,和空闲断连无关。
- 服务端改
connect_timeout:配置文件加connect_timeout = 10,重启生效 - JDBC 连接串里加
?connectTimeout=5000&socketTimeout=30000 - PyMySQL 初始化时传
connect_timeout=5, read_timeout=30
HikariCP / Druid 必须同步配健康检查
只调服务端 wait_timeout 不够——连接池不知道连接已被 MySQL 主动断开,还会把失效连接当“活”的分给业务代码。
必须启用连接有效性验证,并让检测频率略小于服务端超时值(比如服务端设 300 秒,检测间隔设 240 秒):
- HikariCP:
connection-test-query=SELECT 1(MySQL 8.0.22+ 推荐connection-init-sql),validation-timeout=3000,test-on-borrow=false+test-on-return=true - Druid:
testWhileIdle=true,timeBetweenEvictionRunsMillis=240000,minEvictableIdleTimeMillis=300000 - Python(PyMySQL):每次取连接前手动调
conn.ping(reconnect=True),或设autocommit=True避免事务状态残留
net_read_timeout 和 net_write_timeout 容易被忽略
这两个参数控制服务端收发数据的单次阻塞上限,默认分别是 30 秒和 60 秒。它们不决定连接是否断开,但会影响长查询、大数据导入导出、BLOB 字段读写等场景下的中断行为。
如果业务有定时跑报表、ETL 同步或批量写入,且经常触发 Lost connection during query,大概率是这两个值太小:
- 配置文件中设
net_read_timeout = 600、net_write_timeout = 600 - 注意:修改后需重启 MySQL,不能用
SET GLOBAL动态生效 - 它们和
wait_timeout无依赖关系,但共同构成完整的超时防护网











