> 技术文档 > Mysql 连接

Mysql 连接

数据库中,客户端与数据库建立新连接是一个复杂过程,网络层基于 TCP 协议通信建立连接,数据库需要验证客户端的身份,认证通过后数据库分配连接资源,设置会话参数,获取元数据锁(MDL)数据库共享锁连接建立完成后,服务器将连接状态标记为 “空闲”(Sleep),进入等待状态,直到客户端发送 SQL 命令。

长连接是指连接建立后在多次数据库操作(如多次查询、更新)中复用该连接,直到主动关闭或因超时被服务器断开。而短连接每次执行数据库操作时临时建立连接,操作完成后立即关闭连接。

因为连接建立成本,所以建议尽量使用长连接,但是随着连接复用,mysql的内存占用可能大,所以mysql 5.7及以上通过mysql_reset_connection来重新初始化连接资源,不需要重新认证。

连接池的最大连接数

maximumPoolSize是平衡数据库性能与资源利用率的核心参数,设置不当会导致 “连接耗尽”(应用等待连接)或 “数据库过载”(连接过多导致资源竞争)。其合理值需结合数据库承载能力应用并发量查询性能等多维度综合评估

连接池最大连接数不超过数据库的最大连接数,建议为数据库 max_connections 的 50%-80%

SHOW VARIABLES LIKE \'max_connections\'; -- 默认通常为 151,生产环境建议调至 500-1000(根据服务器配置)

主流连接池(如 HikariCP、Druid)都有 “等待队列”(当连接耗尽时,新请求排队等待,而非立即失败),设置时需配合队列长度。

避免 “越大越好”:连接数超过数据库处理能力后,新增连接会导致性能下降(资源竞争抵消复用收益)。

区分 “读写连接”:若使用读写分离,建议为读库和写库分别配置连接池(读库并发更高,可设置更多连接)。

配合其他参数minimumIdle(最小空闲连接):建议设为最大连接数的 50%,避免频繁创建连接。idleTimeout(空闲超时):需小于数据库 wait_timeout,避免连接失效。

动态配置:部分连接池(如 Druid)支持运行时调整最大连接数,可根据业务高峰期(如电商大促)临时扩容。

wait_timeout 

用于控制非交互式连接(通过 mysql 命令行工具以外的方式建立的连接,如应用程序通过 JDBC、ODBC 等驱动创建的连接)的空闲超时时间。当一个连接处于空闲状态(没有执行任何 SQL 操作)的时间超过 wait_timeout 设定值时,MySQL 服务器会自动关闭该连接,释放资源。默认值通常为 28800 秒,即 8 小时。

当连接空闲时间超过 wait_timeout 被服务器关闭,而应用未检测连接有效性继续使用。会 报错MySQL server has gone away,

interactive_timeout 用于控制交互式连接(如 mysql 命令行客户端)的空闲超时时间

-- 查看当前会话的 wait_timeout 值SHOW VARIABLES LIKE \'wait_timeout\';-- 查看全局的 wait_timeout 配置(需权限)SHOW GLOBAL VARIABLES LIKE \'wait_timeout\';-- 仅对当前连接生效,关闭连接后失效SET wait_timeout = 3600; -- 设置为 1 小时-- 对新建立的连接生效,已存在的连接不受影响SET GLOBAL wait_timeout = 3600;

永久生效需修改 MySQL 配置文件(如 my.cnf 或 my.ini),在 [mysqld] 段落中添加:

[mysqld]wait_timeout = 3600interactive_timeout = 3600 # 建议与 wait_timeout 保持一致,避免混淆

为什么需要设置 wait_timeout

  • 释放闲置资源:长期空闲的连接会占用数据库连接数(受 max_connections 限制),若连接数耗尽,新请求会被拒绝(报 Too many connections 错误)。
  • 避免连接失效:部分网络环境(如防火墙)会主动关闭长时间空闲的连接,若数据库端未及时释放,应用可能使用 “已被防火墙关闭” 的连接,导致通信错误(如 Broken pipe)。

合理设置建议

  • 不宜过大:若设置过大(如默认 8 小时),可能导致大量空闲连接堆积,耗尽连接数。
  • 不宜过小:若设置过小(如几秒),正常的短时间空闲连接会被频繁关闭,应用需频繁重建连接,增加开销。
  • 根据业务场景调整,一般 Web 应用可设置为 300 秒(5 分钟),后台任务类应用可适当延长。
  • 在使用数据库连接池的场景中,连接池的最大空闲时间(如 HikariCP 的 idleTimeout)应小于 wait_timeout,避免连接池返回已被 MySQL 关闭的连接。