必须设为相同值,因mysql不自动同步二者;只改wait_timeout而漏interactive_timeout会导致命令行等交互连接仍按默认8小时存活,易产生死连接,生产建议统一设为300~600秒并写入my.cnf的[mysqld]段重启生效。

wait_timeout 和 interactive_timeout 必须设为相同值
MySQL 不会自动同步这两个参数。如果只改 wait_timeout,而漏掉 interactive_timeout,命令行、Navicat 或其他交互式客户端建立的连接仍按默认 28800 秒(8 小时)存活。这些长期空闲连接可能被复用或误留,成为死连接源头。
- 生产环境建议统一设为
600(10 分钟),高并发短事务场景可压到300(5 分钟) - 修改必须写入
my.cnf的[mysqld]段,并重启 MySQL;仅用SET GLOBAL无法持久化,且旧连接不会立即断开 - 检查是否生效:执行
SHOW PROCESSLIST,找State = 'Sleep'且Time > 600的行——若仍有,说明配置未加载,或连接正处在未提交事务中
connect_timeout 要防半开连接,但别设太高
这个参数管的是 TCP 握手 + 认证阶段的等待上限,不是已建连后的空闲时间。攻击者可用大量慢握手请求占满连接槽位。
- 默认
10秒足够大多数场景 - 若用了 LDAP/PAM 认证或链路极差,可临时调到
15,但绝不能超过30 - 它无法通过
SET GLOBAL修改,必须写进配置文件并重启 - 配合
max_connect_errors = 3使用,能快速封禁反复失败的 IP(前提是启用了skip-name-resolve,避免 DNS 查询拖慢判断)
连接池的 maxLifetime 必须比 wait_timeout 少至少 60 秒
光靠 MySQL 断连接没用。服务端 kill 掉连接后,应用若继续复用该连接,下一次操作必然报 MySQL server has gone away。
- HikariCP:设
maxLifetime=540000(9 分钟),对应wait_timeout=600 - Druid:设
maxEvictableIdleTimeMillis=540000 - 别依赖
testOnBorrow或validationQuery,每次取连接都查库开销大;优先用connectionInitSql=SELECT 1做轻量心跳 - 如果应用里有长轮询、延迟提交等逻辑,需确认连接池是否支持
keepaliveTime主动保活
innodb_lock_wait_timeout 设太长会让锁堆积更隐蔽
它不控制连接生命周期,而是控制“一个事务等锁最多忍多久”。设成默认 50 秒,容易掩盖真实问题:
- OLTP 场景建议
10~25秒:够应对网络抖动,又不至于让单个卡顿拖垮接口 - 它不影响死锁检测(那是
innodb_deadlock_detect控制的),只决定“等锁等到放弃”的阈值 - 真正的锁堆积根源常在 SQL 本身:比如慢查询、缺失索引、事务里混了 HTTP 调用——超时参数只是兜底,不是根治
最容易被忽略的是事务边界没显式控制。Spring 的 @Transactional 方法里如果做了文件读写、远程调用或循环处理,事务实际持锁时间远超预期,MySQL 完全不知情。这种连接即使空闲超时也未必能释放锁,因为状态仍是 Active。











