MySQL连接数爆满时,先查SHOW VARIABLES LIKE 'max_connections'、SHOW STATUS LIKE 'Threads_connected'和Threads_running确认是否真满;大量Sleep线程表明连接泄漏或配置失配;SHOW PROCESSLIST需root权限才可见全量,否则易误判;SET GLOBAL max_connections受ulimit、systemd LimitNOFILE及MySQL版本特性限制;8.0+可用admin_port作紧急管理通道。

别急着改 max_connections,90% 的 Too many connections 报错不是上限太低,而是连接没释放、卡在锁或空闲状态——先确认是不是真满了,再查谁在占着不放。
怎么一眼看出是不是真连满了
哪怕应用全连不上,root 本地 socket 还能进(MySQL 预留一个 SUPER 权限紧急连接位)。登录后立刻执行三句:
-
SHOW VARIABLES LIKE 'max_connections';—— 看上限,默认常是 151 -
SHOW STATUS LIKE 'Threads_connected';—— 当前已建连数 -
SHOW STATUS LIKE 'Threads_running';—— 正在干活的线程数;如果前者接近上限但后者极低(比如 498/500 连接里只有 23 个在跑),说明全是Sleep,基本就是泄漏或连接池 idle 超时比wait_timeout还长
为什么 SHOW PROCESSLIST 看不到全部连接
SHOW PROCESSLIST; 默认只显示当前用户权限下的连接。查全量必须用 root 或具备 PROCESS 权限的账号,否则看不到其他应用的连接,容易误判为“没人连”。更准的方式是:
-
SELECT STATE, COUNT(*) AS cnt FROM performance_schema.processlist GROUP BY STATE ORDER BY cnt DESC;—— 快速看连接分布,若大量卡在Waiting for table metadata lock,大概率是元数据锁阻塞 -
SELECT USER, HOST, COUNT(*) FROM information_schema.PROCESSLIST GROUP BY USER, HOST ORDER BY COUNT(*) DESC;—— 定位异常 IP 或账户,同一User+Host出现几十个连接,基本是某个实例泄漏
为什么 SET GLOBAL max_connections 经常不生效
这条命令看着快,实际卡在三道硬门槛上:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
-
ulimit -n返回值低于设定值(如返回 1024,却设max_connections = 2000),MySQL 启动时会自动向下取整 - systemd 管理的服务必须在
/usr/lib/systemd/system/mysqld.service的[Service]段加LimitNOFILE=65536和LimitNPROC=65536,再执行systemctl --system daemon-reload && systemctl restart mysqld - MySQL 8.0.22+ 支持
SET PERSIST max_connections = 1000;,它会写入mysqld-auto.cnf,优先级高于my.cnf—— 若已用此方式,改配置文件也不覆盖
MySQL 8.0 的 admin_port 是最后救命稻草
连接打满时,常规连接全被拒,连 root 都可能进不去。MySQL 8.0+ 提供独立管理通道(admin_port),不走常规连接逻辑,也不计入 max_connections:
- 启用方式:在
my.cnf的[mysqld]段加admin_port = 33062(端口可自定,别超 65535) - 前提:用户需有
SUPER权限或service_connection_admin动态权限 - 验证是否启用:
SELECT @@admin_port, @@admin_address;
这个端口平时不用,但连接数爆满时它就是唯一能进数据库的后门——别等出事才配,上线前就该检查好。










