先查show variables like 'max_connections'、show status like 'threads_connected'和show status like 'max_used_connections'确认是否真爆满;若threads_connected远低于上限,则问题在连接泄漏、慢查询或系统限制,而非连接数不足。

“Too many connections”不是数据库挂了,而是新连接被直接拒之门外——必须立刻查当前连接状态,而不是先改配置。
怎么一眼看出是不是真爆满
登录 MySQL 后第一件事不是调参,而是跑三行命令确认水位:
-
SHOW VARIABLES LIKE 'max_connections';—— 看上限(默认 151,云数据库可能设 1000+) -
SHOW STATUS LIKE 'Threads_connected';—— 看当前活连接数,接近上限才是真危险 -
SHOW STATUS LIKE 'Max_used_connections';—— 看历史峰值,若长期 >95% max_connections,说明要么业务突增,要么有泄漏
如果 Threads_connected 只有 80 而 max_connections 是 151,那报错大概率是应用层在重试或健康检查疯狂建连,不是连接真不够用。
怎么看哪些连接在“占着茅坑不拉屎”
SHOW PROCESSLIST; 是核心诊断命令,重点关注三类连接:
-
State = 'Sleep'且Time > 300:空闲超 5 分钟,基本是应用没关连接或连接池配置失当 -
State = 'Sending data'或'Locked'且Time持续增长:SQL 卡住了,可能是慢查询、锁等待或大事务 - 同一
User+Host出现几十个连接:大概率是某个应用实例泄漏,比如 PHP 脚本异常退出未归还连接
注意:SHOW PROCESSLIST 默认只显示当前用户权限下的连接;查全量需用 root 或具备 PROCESS 权限的账号,否则看不到其他应用的连接。
为什么 SET GLOBAL max_connections 有时不生效
执行 SET GLOBAL max_connections = 500; 后发现值没变?常见原因不是语法错,而是系统级卡点:
- Linux 文件描述符限制太低:
ulimit -n返回 1024,而你想设 2000 → MySQL 启动时自动向下取整,日志里会有Could not increase number of max_open_files - 配置文件写错段落:
max_connections必须放在[mysqld]段下,写在[client]或全局位置无效 - MySQL 8.0.22+ 已用
SET PERSIST持久化过该参数 →my.cnf修改会被忽略,得查mysqld-auto.cnf
验证是否生效,别信配置文件,要查运行时值:SELECT @@global.max_connections;
临时救急但不能依赖的操作
连接打满时,你可能连不上 MySQL,管理员也进不去——这是最致命盲区。MySQL 8.0+ 提供了独立管理通道(admin_port),不走常规连接逻辑,也不计入 max_connections:
- 启用方式:在
my.cnf的[mysqld]段加admin_address=127.0.0.1和admin_port=33062,然后重启 - 连接命令:
mysql -u root -p -h 127.0.0.1 -P 33062,即使常规端口连不上,这个也能进 - 进去后可立即
KILL异常连接,或调wait_timeout缩短空闲释放时间
没开 admin_port 的老版本,只能靠 kill -TERM $MYSQL_PID 安全重启,但会中断所有连接——这本身说明问题已到临界点,不能再只做表面处理。











