MySQL技巧(十四): 连接数过多 (Too many connections):原因 + 排查 + 终极解决方案

线上高频事故:MySQL 突然报 Too many connections,服务雪崩、接口全挂。本文从原因定位、实时排查到永久根治,一套方案搞定所有场景。


一、前言

Too many connections 是 MySQL 最常见的线上故障之一。一旦出现,整个业务几乎不可用:

  • 应用无法连接数据库
  • 接口大量超时
  • 监控告警刷屏
  • 老连接不释放,新连接进不来

很多人只会临时 max_connections 改大,但治标不治本,过几天又炸。

本文带你:快速恢复 → 定位根因 → 彻底根治,生产 & 面试都能用。


二、先看懂三个关键指标

sql

复制代码
-- 最大连接数上限
show variables like 'max_connections';

-- 当前正在使用的连接数
show status like 'Threads_connected';

-- 历史峰值
show status like 'Max_used_connections';

只要 Threads_connected 接近 max_connections,业务就开始报错:

Too many connections


三、连接数满的【超全原因汇总】

1. 应用代码层面原因(最常见)

  1. 连接泄漏
    • 申请连接后未关闭
    • try-catch 异常路径未释放
    • ORM 误用、嵌套事务未释放
  2. 长事务 / 大事务占住连接不释放
    • 事务里调用 HTTP/RPC/ 第三方接口
    • 事务里循环处理大量数据
    • 事务未提交 / 回滚,连接一直持有
  3. 短连接风暴
    • 每次请求都新建连接
    • 脚本语言(PHP/Python)无连接池
    • 高并发下疯狂创建 / 销毁连接
  4. 连接池配置不合理
    • max-active 设置过大
    • 多个微服务连接数总和打爆数据库
    • 连接池等待队列过长,导致连接堆积
  5. 应用重启不彻底
    • 旧进程未杀死,继续持有连接
    • 多实例部署重复占用连接

2. SQL 与索引问题导致连接堆积

  1. 大量慢查询阻塞连接
    • 未加索引、全表扫描
    • 大表 JOIN、子查询嵌套
    • 文件排序、临时表导致 SQL 执行极慢
  2. 锁等待严重
    • 行锁冲突、表锁、间隙锁
    • 热点行更新导致大量事务阻塞
    • 连接占着不释放,新连接进不来
  3. 统计信息过旧导致执行计划走错
    • 查询瞬间变慢,连接暴增
  4. 大量统计 / 报表类查询压垮数据库
    • 后台任务、定时任务集中执行
    • 占用大量连接长时间不释放

3. MySQL 自身配置与运行问题

  1. max_connections 默认太小(默认仅 151)
  2. 文件描述符不足(系统级限制)
    • Linux: open files 限制太小
    • 导致 MySQL 无法新建连接
  3. DNS 反向解析卡顿
    • MySQL 每次连接反查主机名
    • 网络慢 → 连接建立极慢 → 堆积
  4. 线程缓存不足
    • thread_cache_size 过小
    • 频繁创建销毁线程,性能下降,连接堆积
  5. 空闲连接超时设置过长
    • wait_timeout /interactive_timeout 太大
    • sleep 连接长期不释放,占满连接数
  6. MySQL 负载过高
    • CPU 100%、IO 高、磁盘满
    • 执行缓慢,连接无法快速释放
  7. binlog 刷盘、redo 日志竞争
    • 高写入下磁盘瓶颈,事务提交慢
  8. 内存不足 OOM 前兆
    • 内存占满,性能急剧下降
    • 连接处理不过来

4. 架构与流量问题

  1. 流量突增 / 活动压测
    • 秒杀、促销、爬虫突增
  2. 分布式架构连接数叠加
    • 几十个微服务连同一个 MySQL
    • 单个服务合理,总和爆炸
  3. 读写分离失效
    • 所有读都走主库
    • 主库连接瞬间打满
  4. 网关 / 代理重试风暴
    • 超时重试、失败重试
    • 指数级放大请求,连接数翻倍增长
  5. 监控、备份、巡检工具占用连接
    • Prometheus、Zabbix、监控脚本
    • 每秒连接一次,累积大量连接

5. 网络与环境问题

  1. 网络抖动 / 延迟高
    • 应用与 MySQL 之间网络不稳定
    • 连接建立慢、释放慢
  2. TCP 参数不合理
    • TIME_WAIT 过多
    • 端口耗尽、握手缓慢
  3. 虚拟机 / 容器资源限制
    • Docker/K8s CPU / 内存限制
    • MySQL 性能下降,连接堆积
  4. 云数据库底层性能波动
    • 磁盘性能突降、实例拥挤

6. 恶意攻击与异常行为

  1. CC 攻击、恶意刷接口
  2. 漏洞扫描、暴力破解数据库
  3. 死锁循环重试
    • 业务死锁 → 报错重试 → 更多连接
  4. 大量未授权连接尝试

四、3 分钟应急恢复方案

1. 优先登录 MySQL

普通方式连不上时用 socket:

bash

运行

复制代码
mysql -uroot -p -S /tmp/mysql.sock

2. 临时加大连接数

sql

复制代码
set global max_connections = 1000;

3. 批量清理异常长连接

sql

复制代码
select concat('kill ',id,';')
from information_schema.processlist
where command='Sleep' and time>60;

4. 关闭 DNS 解析(立刻缓解)

sql

复制代码
set global skip_name_resolve = ON;

5. 调整超时时间

sql

复制代码
set global wait_timeout = 120;
set global interactive_timeout = 120;

五、精准排查:定位谁在占连接

1. 按用户统计

sql

复制代码
select user,count(*) cnt
from information_schema.processlist
group by user order by cnt desc;

2. 按 IP 统计(定位服务)

sql

复制代码
select substring_index(host,':',1) ip,count(*) cnt
from information_schema.processlist
group by ip order by cnt desc;

3. 查慢查询

sql

复制代码
select * from information_schema.processlist
where command='Query' and time>3 order by time desc;

4. 查长 Sleep 连接

sql

复制代码
select id,user,host,time,info
from information_schema.processlist
where command='Sleep' and time>30;

六、终极解决方案(永久根治)

1. 应用层

  • 统一使用连接池(HikariCP/Druid)
  • 控制单个服务连接数 15~30
  • 禁止长事务,事务只做 DB 操作
  • 异常必须释放连接
  • 接入限流、熔断、降级

2. MySQL 配置优化(my.cnf)

ini

复制代码
max_connections = 1000
wait_timeout = 120
interactive_timeout = 120
skip_name_resolve = 1
thread_cache_size = 300
open_files_limit = 65535

3. 架构层

  • 读写分离
  • 分库分表
  • 热点服务独立数据库
  • 使用数据库中间件(ShardingSphere/ProxySQL)

4. 治理层

  • 慢查询治理
  • 索引优化
  • 禁止大事务
  • 定时任务错峰执行
  • 监控连接数、使用率、慢查询

六、总结

Too many connections 本质就三大类:

  1. 应用没正确释放连接 / 连接池乱配
  2. SQL 慢、锁等待、事务长导致连接堆积
  3. 流量过大 + 架构不合理 + 配置过小

急救只能临时扩容,根治必须从应用、SQL、架构、配置四管齐下。

原创不易,点赞 + 收藏 + 关注,后续持续更新 MySQL 线上故障排查实战。

相关推荐
lifewange2 小时前
java连接Mysql数据库
java·数据库·mysql
不写八个4 小时前
PHP教程004:php链接mysql数据库
数据库·mysql·php
计算机学姐5 小时前
基于SpringBoot的咖啡店管理系统【个性化推荐+数据可视化统计+配送信息】
java·vue.js·spring boot·后端·mysql·信息可视化·tomcat
٩( 'ω' )و2606 小时前
MySQL基础
数据库·mysql
生命不息战斗不止(王子晗)6 小时前
mysql基础语法面试题
java·数据库·mysql
流星白龙6 小时前
【MySQL】19.MySQL用户管理
android·mysql·adb
qq_283720057 小时前
mysql技巧(十二):内存优化Buffer Pool 缓冲原理详解与配置
mysql·缓冲
xiaokangzhe8 小时前
MySQL主从复制读写分离笔记
笔记·mysql·adb
羊小蜜.8 小时前
Mysql 01:基础查询(SELECT)全解——从单表到多字段的完整语法
数据库·mysql·查询