一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

线上MySQL提示Too many connections超载报错该如何快速扩容并排查?

时间:2026-07-14 10:01:03 编辑:袖梨 来源:一聚教程网

90%的“Too many connections”源于连接未释放而非max_connections过小;应先用socket直连执行SHOW VARIABLES LIKE 'max_connections'、SHOW STATUS LIKE 'Threads_connected'和SHOW STATUS LIKE 'Threads_running'确认是否真满,若Threads_connected接近上限而Threads_running极低,说明大量连接卡在Sleep状态,多为应用未关闭或连接池配置不当。

别急着调 max_connections,90% 的 “Too many connections” 不是连接不够用,而是连接没释放、堆在那儿占坑——先确认是不是真连满了,再决定扩不扩容。

怎么快速判断是不是真连满了

哪怕应用连不上,MySQL 会预留一个 SUPER 权限的紧急连接位(max_connections + 1),所以你还能用 socket 登进去:

  • 执行 SHOW VARIABLES LIKE 'max_connections'; —— 看上限,默认常是 151
  • 执行 SHOW STATUS LIKE 'Threads_connected'; —— 看当前已建连数
  • 执行 SHOW STATUS LIKE 'Threads_running'; —— 看正在干活的线程数

如果 Threads_connected 接近上限,但 Threads_running 极低(比如 2/498),说明几百个连接全卡在 Sleep 状态,基本就是应用没关连接或连接池 idleTimeout 比 MySQL 的 wait_timeout 还长。

临时扩容为什么经常失效

SET GLOBAL max_connections = 1000; 看似快,但有三道硬门槛拦着:

  • Linux 系统级文件描述符限制:ulimit -n 默认常为 1024,设到 1000 就可能失败;Docker 容器里没加 --ulimit nofile=65536:65536,光改 MySQL 配置无效
  • 已经连不上了?那这条命令根本执行不了——得靠 kill -TERM 主进程(不是 mysqld_safe)安全重启
  • 内存扛不住:每个连接平均吃 512KB~2MB,设到 2000 连接,光连接本身就要 1~4GB 内存,容易触发 OOM

连接池配置比 MySQL 参数更关键

多数线上事故根子在应用侧。比如 Druid 或 HikariCP,常见错配:

  • max-active(或 maximumPoolSize)设得比 max_connections 还高,多个服务一起压就爆
  • min-idlemax-wait 没调,连接用完不归还、等超时才扔,堆满 Sleep
  • idleTimeout(连接池) > wait_timeout(MySQL),导致连接池以为连接还活着,MySQL 却已单方面断开,后续复用时报错或卡死

正确做法是:连接池 idleTimeout 必须 ≤ MySQL 的 wait_timeout,建议都设成 300 秒(5 分钟)起手,再根据业务微调。

永久生效要改哪些地方

编辑 /etc/my.cnf/etc/mysql/my.cnf,在 [mysqld] 段加:

max_connections = 500wait_timeout = 300interactive_timeout = 300max_user_connections = 100

注意:max_user_connections 是防止单个应用(比如某个微服务)占满所有连接,留余量给管理账号和其它服务。改完必须验证语法:mysqld --validate-config,并确认没被其他配置文件覆盖(mysqld --verbose --help | grep "Default options" 查加载顺序)。

真正难的不是改数字,而是确认每个 Sleep 连接背后有没有未提交事务、慢查询或异常退出的脚本——这些才是反复爆满的伏笔。

热门栏目