MySQL连接超时需分设connect_timeout、wait_timeout、interactive_timeout:前者控制TCP握手认证超时(建议3~5秒),后两者控制空闲连接断开时机(建议统一设为300或600秒),且连接池参数须与之对齐。

MySQL生产环境的连接超时参数不能只设一个值,必须区分 connect_timeout、wait_timeout、interactive_timeout 三者作用域和生效时机,否则会出现“连接刚建好就断”或“长事务被静默杀掉”这类隐蔽故障。
connect_timeout 控制的是 TCP 握手阶段,不是 SQL 执行时间
这个参数只影响客户端发起连接请求后,等待 MySQL 完成三次握手和初始认证响应的最大秒数。它不参与后续任何查询或空闲等待。
- 默认值是 10 秒,线上建议调低到
3~5秒:网络抖动或服务宕机时能更快失败,避免应用线程卡死 - 修改方式为动态 SET:
SET GLOBAL connect_timeout = 5,无需重启,但只对新连接生效 - 注意:Java 的
com.mysql.cj.jdbc.Driver会把 JDBC URL 中的connectTimeout(毫秒)优先级设得更高,会覆盖 server 端的connect_timeout值 - 常见错误现象:
java.sql.SQLNonTransientConnectionException: Could not create connection to database server,但telnet host 3306是通的——大概率是认证慢或 DNS 解析卡住,而非网络不通
wait_timeout 和 interactive_timeout 决定空闲连接何时被 MySQL 主动断开
这两个参数控制“连接建好之后,不干活等多久会被踢”。区别在于:wait_timeout 用于非交互式连接(比如应用服务器用连接池连过来的),interactive_timeout 用于交互式连接(比如你用 mysql 命令行登录进去不敲命令)。
- 默认都是 28800 秒(8 小时),生产环境必须改短;推荐设为
300(5 分钟)或600(10 分钟) - 务必让两者值一致,否则连接池可能因“本该复用的连接被 server 断了”而报
MySQL server has gone away - 如果应用层用了连接池(如 HikariCP、SQLAlchemy),一定要配
connection-test-query或pool_pre_ping=True,否则空闲连接在被wait_timeout杀掉后,池子还当它是活的 - 别指望靠加大
wait_timeout来“解决连接断开问题”——那只是把问题延迟暴露,实际掩盖了连接池配置不合理或应用未正确归还连接的根因
连接池侧的超时设置必须和 MySQL 服务端对齐
应用层连接池(比如 SQLAlchemy、Druid、HikariCP)有自己的超时逻辑,如果不和 MySQL 的 wait_timeout 配合,就会出现“池子里全是过期连接”的雪球效应。
- 连接池的
maxLifetime(如 HikariCP)应略小于 MySQL 的wait_timeout,例如 MySQL 设了300,池子就设280秒,留出缓冲窗口 -
validationTimeout(验证超时)要小于connectionTimeout(获取连接超时),否则健康检查本身就会拖慢连接获取 - PyMySQL 用户要注意:
connect_timeout是建立 TCP 连接的上限,而read_timeout和write_timeout控制后续通信阶段,三者需分别设值,不能只设一个 - Dify 或其他 Python 后端若用 SQLAlchemy,
pool_recycle=3600这种“一小时一换”的做法,在wait_timeout=300的 MySQL 下毫无意义——连接早被 server 端踢掉了
真正容易被忽略的点是:MySQL 的 wait_timeout 修改后,已存在的连接不会立即重置倒计时,而是从它们各自空闲开始时刻起算。这意味着你改完参数,得等最老的那批空闲连接自然过期,才能看到效果。上线前最好主动 kill 掉旧连接:KILL CONNECTION xxx,或者滚动重启应用服务。


















