概述
MySQL连接数超限是数据库运维中常见的问题,通常表现为应用报错“Too many connections”或服务响应缓慢。若不及时处理,可能导致业务中断。本文提供一套完整的应对策略,涵盖紧急扩容和长期优化两个维度。
临时扩容方案
动态调整max_connections
在不重启数据库实例的前提下,可通过命令行或控制台临时提高最大连接数:
SET GLOBAL max_connections = 500;
该调整立即生效,但重启后失效。建议配合连接池设置合理上限,避免内存耗尽。
调整应用连接池
若应用使用连接池(如HikariCP、Druid),可临时调大最大连接数:
- HikariCP:修改
maximumPoolSize参数,例如从20增至50。 - Druid:调整
maxActive。
注意:增大连接池会占用更多数据库服务端资源,需同步评估服务器负载。
清理空闲连接与重启服务
紧急情况下,可执行以下操作快速释放连接:
- 使用
SHOW PROCESSLIST;检查长时间运行的查询,使用KILL命令终止异常连接。 - 在确保数据一致性的前提下,重启应用服务以断开所有客户端连接。
永久优化方案
应用层优化
从源头减少连接占用:
- 使用连接池管理数据库连接,避免频繁创建/销毁;设置合理的最小空闲连接数(如5-10)和最大等待时间。
- 优化业务逻辑,缩短数据库操作时长,降低并发连接需求。
- 开启SQL预编译和缓存,减少重复执行。
数据库参数调优
调整以下核心参数:
- wait_timeout:非交互连接超时(建议60-300秒)。
- interactive_timeout:交互连接超时(建议120-600秒)。
- thread_cache_size:缓存线程数量(建议设置为CPU核心数的2-4倍)。
- max_connections:根据服务器内存
(可用内存 / 每个连接内存开销)设定合理值,通常小型实例设为200-500,大型实例可适当提高。
查询与索引优化
慢查询是连接长时间占用的主要原因:
- 启用
slow_query_log,分析慢查询日志。 - 对高频查询添加索引,避免全表扫描。
- 使用
EXPLAIN分析执行计划,改写低效SQL。
架构扩展
当单实例无法满足持久化需求时,考虑:
- 读写分离:将查询请求分流到只读实例,减轻主库连接压力。
- 分库分表:水平拆分数据,分散连接至多个数据库实例。
- 部署连接代理(如ProxySQL、MaxScale)集中管理后端连接池。
总结
临时扩容能快速恢复服务,但不可长期依赖;永久优化需结合应用、参数、查询和架构多维度改进。建议定期监控连接使用率,设置告警阈值(如达到80%即触发通知),防患于未然。对于核心业务,可预留20%-30%的冗余连接数,平衡性能与稳定性。