wait_timeout控制非交互式连接(如java/python/go应用通过jdbc等驱动建立的连接),需与interactive_timeout同步设置才生效,且仅影响新建连接。

wait_timeout 控制的是哪类连接?
它只管非交互式连接,也就是应用代码(Java/Python/Go)通过 JDBC、PyMySQL、mysqlclient 等驱动建立的连接。这类连接默认走 wait_timeout,不是 interactive_timeout。你用 mysql -u root -p 手动连进去的会话才走后者——所以调参时必须两个一起设,否则容易只改了一个却没效果。
为什么直接 SET GLOBAL wait_timeout 没用?
常见错觉是执行了 SET GLOBAL wait_timeout = 300,再查 SHOW VARIABLES LIKE 'wait_timeout' 发现值没变。这是因为该命令查的是当前会话变量,不是全局值。要确认是否生效,得用:SHOW GLOBAL VARIABLES LIKE 'wait_timeout'。
更重要的是:这个设置只对新建立的连接生效。已存在的 Sleep 连接仍沿用建连时继承的老值,不会自动刷新。所以改完参数后,SHOW PROCESSLIST 里那些“睡着”的连接还得手动 KILL 或等它们自然超时。
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
怎么避免改了 wait_timeout 反而引发重连风暴?
关键在客户端连接池和 MySQL 的协同:
-
wait_timeout必须大于连接池的max-lifetime(如 HikariCP 的maxLifetime),且至少留出 30–60 秒缓冲。例如 MySQL 设为 1800 秒(30 分钟),池子就设 1700 秒。 - 连接池必须开启验证机制:
connection-test-query=SELECT 1(MySQL 8.0+ 推荐用isValid()) +validation-timeout=3000。 - 禁用
test-on-borrow=true(每次取连接都查一次),改用轻量的保活:keepalive-time=30000(每 30 秒发一次 SELECT 1)。 - 别在应用里写
SET SESSION wait_timeout = ...,这绕过统一管控,还可能因权限不足静默失败。
清理完空闲连接,内存还在涨?
因为 wait_timeout 只断开连接,不清理会话残留资源。大量 Sleep 连接长期挂着,会累积:
- 临时表(
CREATE TEMPORARY TABLE)不显式DROP就一直占内存和磁盘 - 大体积用户变量(如
@blob := LOAD_FILE(...))不会自动释放 - 预处理语句(
PREPARE stmt FROM)不DEALLOCATE PREPARE就持续占用内存
真正可靠的清理动作是连接归还池前调用 mysql_reset_connection()(MySQL 5.7.3+ / Connector/J 8.0.14+ 支持),它比简单断连更彻底——清变量、删临时表、重置会话状态。没这个能力的旧驱动,就得靠业务层主动 SET @var = NULL 和记录临时表名做 DROP。










