1. 问题现象与紧急处理当MySQL突然抛出Too many connections错误时整个系统可能瞬间陷入瘫痪状态。这个报错意味着所有可用连接都被占用新的客户端无法建立连接。作为DBA我处理过数十次这类生产事故总结出一套快速止血方法论。1.1 30秒应急处理方案遇到连接爆满时按这个优先级操作立即释放空闲连接最快速有效-- 查看所有连接状态 SHOW PROCESSLIST; -- 批量清理Sleep状态的空闲连接危险操作需评估业务影响 SELECT CONCAT(KILL , id, ;) FROM information_schema.processlist WHERE Command Sleep AND Time 300 INTO OUTFILE /tmp/kill_idle.sql; SOURCE /tmp/kill_idle.sql;临时扩容连接数治标不治本-- 不重启服务的情况下动态调整 SET GLOBAL max_connections 500;超级管理员通道最后手段 如果普通账号已无法连接使用--skip-grant-tables参数启动MySQL但会带来严重安全隐患操作后必须立即恢复。警告KILL操作可能导致事务中断高并发时段慎用。我曾遇到某电商大促时误杀支付事务连接导致订单状态不一致的惨痛教训。2. 根因分析与深度排查2.1 连接泄漏的三大典型场景通过分析上百个案例我发现连接泄漏主要有这些模式连接池配置不当最大连接数设置过高超过实例内存承受能力最小空闲连接数设置不合理未正确配置连接回收策略应用层资源未释放// 典型错误示例未关闭的连接 try { Connection conn dataSource.getConnection(); // 业务代码... // 忘记conn.close() } catch (Exception e) { // 异常处理... }慢查询堆积-- 查看运行时间超过30秒的查询 SELECT * FROM information_schema.processlist WHERE Command ! Sleep AND Time 30 ORDER BY Time DESC;2.2 诊断工具箱这是我的常用排查命令组合-- 查看连接数使用情况 SHOW STATUS LIKE Threads_connected; SHOW VARIABLES LIKE max_connections; -- 按客户端IP统计连接数 SELECT SUBSTRING_INDEX(HOST,:,1) AS client_ip, COUNT(*) AS connection_count FROM information_schema.processlist GROUP BY client_ip ORDER BY connection_count DESC; -- 检查是否有事务长时间未提交 SELECT * FROM information_schema.innodb_trx ORDER BY trx_started ASC LIMIT 10;3. 连接池优化实战3.1 Druid连接池黄金配置以阿里Druid为例推荐生产环境配置# 基础配置 druid.initialSize5 druid.maxActive50 druid.minIdle5 # 关键回收策略 druid.testWhileIdletrue druid.timeBetweenEvictionRunsMillis60000 druid.minEvictableIdleTimeMillis300000 druid.validationQuerySELECT 1 # 泄漏检测 druid.removeAbandonedtrue druid.removeAbandonedTimeout300 druid.logAbandonedtrue3.2 不同场景下的参数调整突发流量场景druid.maxActive100 druid.maxWait5000 # 适当增加等待超时定时任务场景druid.timeBetweenConnectErrorMillis30000 # 避免频繁重试微服务场景druid.filtersstat,wall # 开启SQL防火墙4. 长效预防机制4.1 监控体系建设建议配置这些监控项连接数使用率阈值告警80%长时间运行事务监控30s连接获取时间监控1sPrometheus示例配置- alert: MySQLHighConnections expr: mysql_global_status_threads_connected / mysql_global_variables_max_connections 0.8 for: 5m labels: severity: warning annotations: summary: MySQL连接数使用率过高 (instance {{ $labels.instance }}) description: 当前连接数: {{ $value }}%4.2 压力测试建议使用sysbench进行连接池压测sysbench oltp_read_write \ --db-drivermysql \ --mysql-host127.0.0.1 \ --mysql-port3306 \ --mysql-usertest \ --mysql-passwordtest \ --mysql-dbsbtest \ --threads100 \ --time300 \ --report-interval10 \ prepare5. 典型案例分析5.1 电商秒杀事故复盘某次618大促期间MySQL连接数突然飙升至上限。通过分析发现商品详情页没有启用缓存直接穿透到DB连接池maxActive设置过小仅20没有熔断机制持续重试导致雪崩解决方案增加Redis缓存层调整连接池参数druid.maxActive200 druid.maxWait1000 # 快速失败引入Hystrix熔断5.2 连接泄漏的隐蔽案例某金融系统每天凌晨准时出现连接泄漏最终发现是报表生成任务中def generate_report(): conn get_connection() # 没有try-finally块 # 生成报表代码... if report_type complex: return # 提前返回导致conn未关闭 conn.close()修复方案使用上下文管理器确保连接释放添加连接泄漏检测日志设置合理的超时时间6. 高级技巧与工具6.1 Performance Schema分析启用高级监控-- 开启连接追踪 UPDATE performance_schema.setup_consumers SET ENABLED YES WHERE NAME LIKE events_waits%; -- 查看连接等待事件 SELECT * FROM performance_schema.events_waits_history_long WHERE EVENT_NAME LIKE wait/io/socket%;6.2 pt-kill自动清理工具配置智能kill规则pt-kill --hostlocalhost --usermonitor --passwordxxx \ --match-commandQuery --busy-time60 --kill --print7. 架构层面的优化对于高并发系统建议读写分离降低主库压力使用ProxySQL实现连接池复用重要业务使用独立实例考虑使用MySQL线程池插件线程池配置示例[mysqld] thread_handlingpool-of-threads thread_pool_size32 thread_pool_max_threads1000我在实际运维中发现合理的连接池配置配合完善的监控可以预防90%的连接数问题。特别是在微服务架构下每个服务都应独立评估自己的连接需求避免连接风暴影响整个数据库集群。