出现“too many connections”错误时,90%是连接泄漏或空闲连接堆积所致,应先检查连接状态、优化超时设置及应用层连接关闭逻辑,而非盲目调大max_connections。

Too many connections 错误出现时,先别改 max_connections
报这个错,90% 的情况不是连接数真不够,而是连接泄漏或空闲连接堆积。盲目调大 max_connections 只会让内存吃紧、响应变慢,甚至触发 OOM。真正该做的,是立刻确认当前连接状态:
-
SHOW VARIABLES LIKE 'max_connections';—— 看上限(默认 151,云数据库常设 1000+) -
SHOW STATUS LIKE 'Threads_connected';—— 看当前活连接数,接近上限才是真爆满 -
SHOW PROCESSLIST;—— 重点看State列:Sleep时间超 300 秒、Cleaning up多、或Query卡在Sending data,基本锁定问题类型
查到大量 Sleep 连接,大概率是应用没关连接
ORM(如 Django 默认配置)、脚本直连、或未走连接池逻辑的代码,常会复用连接但不主动 close()。尤其当 wait_timeout 和 interactive_timeout 设得过大(比如 28800 秒),Sleep 连接能挂 8 小时不释放。
- 临时缓解:运行
SET GLOBAL wait_timeout = 60;和SET GLOBAL interactive_timeout = 60;,让空闲连接 60 秒后自动断开 - 根本解法:检查应用层是否调用了
connection.close()或是否配置了连接池的回收策略(如 HikariCP 的idleTimeout) - 注意:
wait_timeout不影响正在执行的查询,只作用于空闲连接;改完需观察应用是否因连接被断而频繁重连
真要调 max_connections,必须同步处理三个限制
只改 max_connections 是无效操作——操作系统文件描述符限制、MySQL 内存开销、连接池配置三者任一卡住,都会让新连接建不起来。
- Linux 层:检查
ulimit -n,若为默认 1024,而你设了max_connections = 2000,实际最多只能建 1024 连接;需在 systemd service 文件中加LimitNOFILE=65536并重启 - 内存层:每个连接约占 256KB–1MB 内存(取决于
sort_buffer_size等),16GB 物理内存机器设超 1000 易拖垮系统 - 应用层:连接池最大值(如 HikariCP 的
maximumPoolSize)必须 ≤ MySQL 的max_connections,否则池子会抢光所有连接,其他服务直接连不上
MySQL 8.0+ 必开 admin_port,否则连不上就杀不了连接
当 max_connections 被占满,普通账号连都连不进去,管理员也进不去——这是最致命的盲区。MySQL 8.0 引入了独立管理通道,不走常规连接逻辑,也不计入 max_connections。
- 启用方式:在
my.cnf的[mysqld]段加admin_address=127.0.0.1和admin_port=33062,然后重启 - 验证是否生效:
SELECT @@admin_address, @@admin_port, @@create_admin_listener_thread;返回 1 表示已开 - 使用:
mysql -h 127.0.0.1 -P 33062 -u root -p直连,执行KILL QUERY <code>id或SHOW PROCESSLIST,无需担心“连不上就杀不了”
线程池不是官方 MySQL 的标配,Percona/MariaDB 才原生支持;官方版即使装了插件,稳定性也远不如前者。所以别把线程池当作万能解,优先盯紧连接生命周期和资源配比——很多“连接数过多”,其实只是连接没归还而已。











