1. 问题现象与背景分析上周五凌晨2点37分我负责的电商促销系统监控突然告警前端页面大面积出现数据库连接失败错误。登录服务器查看MySQL日志满屏的ERROR 1040 (HY000): Too many connections报错。这种连接数打满的情况在流量高峰期尤其常见但解决起来需要系统化的思路。MySQL默认的最大连接数是151个5.7版本当应用并发请求超过这个数值时新连接就会被拒绝。这种情况通常由三种原因导致应用层连接泄漏未正确关闭连接突发流量超过数据库承载能力连接池配置不合理最大连接数设置过高重要提示千万不要在生产环境直接修改max_connections参数了事这就像给漏水的水管加压可能引发更严重的系统崩溃。2. 紧急处理方案5分钟止损2.1 临时增加连接数上限通过MySQL客户端执行需要SUPER权限-- 查看当前连接数和配置 SHOW STATUS LIKE Threads_connected; SHOW VARIABLES LIKE max_connections; -- 临时调整到300重启失效 SET GLOBAL max_connections 300;这个操作能立即缓解连接拒绝的问题但要注意每个连接会占用约8MB内存默认配置300连接 ≈ 2.4GB额外内存需求必须配合后续监控观察内存使用情况2.2 快速释放空闲连接使用以下命令识别并kill空闲连接-- 查看所有连接详情 SELECT * FROM information_schema.processlist WHERE COMMAND ! Sleep ORDER BY TIME DESC; -- 批量清理空闲超过10分钟的连接 SELECT CONCAT(KILL , id, ;) FROM information_schema.processlist WHERE COMMAND Sleep AND TIME 600 INTO OUTFILE /tmp/kill_idle.sql; SOURCE /tmp/kill_idle.sql;3. 根因分析与持久化配置3.1 连接泄漏检测方法在应用服务器执行需netstat命令# 统计各IP到MySQL的连接数 netstat -ant | grep 3306 | awk {print $5} | cut -d: -f1 | sort | uniq -c | sort -n # 查看ESTABLISHED状态的连接 lsof -i :3306 | grep -i estab典型泄漏表现同一进程的连接数持续增长连接存活时间异常长300秒连接关闭状态为CLOSE_WAIT3.2 永久修改连接数配置编辑MySQL配置文件CentOS 7路径vim /etc/my.cnf在[mysqld]段添加max_connections 500 wait_timeout 300 interactive_timeout 300参数说明wait_timeout非交互连接空闲超时秒interactive_timeout交互连接空闲超时秒建议值生产环境300-600秒重启MySQL生效systemctl restart mysqld4. 连接池优化实战4.1 应用层配置建议以Java的HikariCP为例推荐配置# 连接池大小 (核心数 * 2) 有效磁盘数 spring.datasource.hikari.maximum-pool-size20 spring.datasource.hikari.minimum-idle5 spring.datasource.hikari.idle-timeout30000 spring.datasource.hikari.leak-detection-threshold60000关键参数maximum-pool-size不要超过MySQL的max_connections的80%leak-detection-threshold连接泄漏检测阈值毫秒4.2 监控方案实施配置Prometheus监控指标- job_name: mysql static_configs: - targets: [mysql-server:9104] metrics_path: /metrics关键监控项mysql_global_status_threads_connectedmysql_global_variables_max_connectionsmysql_global_status_aborted_connects告警规则示例alert: MySQLHighConnections expr: mysql_global_status_threads_connected / mysql_global_variables_max_connections 0.8 for: 5m5. 深度优化技巧5.1 连接复用方案对于微服务架构建议使用Service Mesh实现连接池共享配置MySQL线程池插件INSTALL PLUGIN thread_pool SONAME thread_pool.so;5.2 性能压测方法使用sysbench模拟并发sysbench oltp_read_write \ --db-drivermysql \ --mysql-host127.0.0.1 \ --mysql-port3306 \ --mysql-usertest \ --mysql-passwordtest \ --mysql-dbsbtest \ --tables10 \ --table-size100000 \ --threads256 \ --time300 \ --report-interval10 \ run观察指标Queries per second (QPS)95th percentile latencyErrors count6. 故障复盘checklist每次出现连接数问题后建议检查[ ] 应用日志中是否有未关闭连接的堆栈[ ] 慢查询日志分析long_query_time1s[ ] 连接来源IP分布是否合理[ ] 连接存活时间直方图[ ] 连接建立频率时序图我在去年双十一大促期间通过这套方法将连接泄漏导致的故障从平均每月1.2次降为零。关键是要建立连接生命周期监控体系而不是简单调大参数。现在我们的监控看板会实时显示每个应用的连接池状态任何异常波动都会触发告警。
MySQL连接数打满的紧急处理与优化方案
1. 问题现象与背景分析上周五凌晨2点37分我负责的电商促销系统监控突然告警前端页面大面积出现数据库连接失败错误。登录服务器查看MySQL日志满屏的ERROR 1040 (HY000): Too many connections报错。这种连接数打满的情况在流量高峰期尤其常见但解决起来需要系统化的思路。MySQL默认的最大连接数是151个5.7版本当应用并发请求超过这个数值时新连接就会被拒绝。这种情况通常由三种原因导致应用层连接泄漏未正确关闭连接突发流量超过数据库承载能力连接池配置不合理最大连接数设置过高重要提示千万不要在生产环境直接修改max_connections参数了事这就像给漏水的水管加压可能引发更严重的系统崩溃。2. 紧急处理方案5分钟止损2.1 临时增加连接数上限通过MySQL客户端执行需要SUPER权限-- 查看当前连接数和配置 SHOW STATUS LIKE Threads_connected; SHOW VARIABLES LIKE max_connections; -- 临时调整到300重启失效 SET GLOBAL max_connections 300;这个操作能立即缓解连接拒绝的问题但要注意每个连接会占用约8MB内存默认配置300连接 ≈ 2.4GB额外内存需求必须配合后续监控观察内存使用情况2.2 快速释放空闲连接使用以下命令识别并kill空闲连接-- 查看所有连接详情 SELECT * FROM information_schema.processlist WHERE COMMAND ! Sleep ORDER BY TIME DESC; -- 批量清理空闲超过10分钟的连接 SELECT CONCAT(KILL , id, ;) FROM information_schema.processlist WHERE COMMAND Sleep AND TIME 600 INTO OUTFILE /tmp/kill_idle.sql; SOURCE /tmp/kill_idle.sql;3. 根因分析与持久化配置3.1 连接泄漏检测方法在应用服务器执行需netstat命令# 统计各IP到MySQL的连接数 netstat -ant | grep 3306 | awk {print $5} | cut -d: -f1 | sort | uniq -c | sort -n # 查看ESTABLISHED状态的连接 lsof -i :3306 | grep -i estab典型泄漏表现同一进程的连接数持续增长连接存活时间异常长300秒连接关闭状态为CLOSE_WAIT3.2 永久修改连接数配置编辑MySQL配置文件CentOS 7路径vim /etc/my.cnf在[mysqld]段添加max_connections 500 wait_timeout 300 interactive_timeout 300参数说明wait_timeout非交互连接空闲超时秒interactive_timeout交互连接空闲超时秒建议值生产环境300-600秒重启MySQL生效systemctl restart mysqld4. 连接池优化实战4.1 应用层配置建议以Java的HikariCP为例推荐配置# 连接池大小 (核心数 * 2) 有效磁盘数 spring.datasource.hikari.maximum-pool-size20 spring.datasource.hikari.minimum-idle5 spring.datasource.hikari.idle-timeout30000 spring.datasource.hikari.leak-detection-threshold60000关键参数maximum-pool-size不要超过MySQL的max_connections的80%leak-detection-threshold连接泄漏检测阈值毫秒4.2 监控方案实施配置Prometheus监控指标- job_name: mysql static_configs: - targets: [mysql-server:9104] metrics_path: /metrics关键监控项mysql_global_status_threads_connectedmysql_global_variables_max_connectionsmysql_global_status_aborted_connects告警规则示例alert: MySQLHighConnections expr: mysql_global_status_threads_connected / mysql_global_variables_max_connections 0.8 for: 5m5. 深度优化技巧5.1 连接复用方案对于微服务架构建议使用Service Mesh实现连接池共享配置MySQL线程池插件INSTALL PLUGIN thread_pool SONAME thread_pool.so;5.2 性能压测方法使用sysbench模拟并发sysbench oltp_read_write \ --db-drivermysql \ --mysql-host127.0.0.1 \ --mysql-port3306 \ --mysql-usertest \ --mysql-passwordtest \ --mysql-dbsbtest \ --tables10 \ --table-size100000 \ --threads256 \ --time300 \ --report-interval10 \ run观察指标Queries per second (QPS)95th percentile latencyErrors count6. 故障复盘checklist每次出现连接数问题后建议检查[ ] 应用日志中是否有未关闭连接的堆栈[ ] 慢查询日志分析long_query_time1s[ ] 连接来源IP分布是否合理[ ] 连接存活时间直方图[ ] 连接建立频率时序图我在去年双十一大促期间通过这套方法将连接泄漏导致的故障从平均每月1.2次降为零。关键是要建立连接生命周期监控体系而不是简单调大参数。现在我们的监控看板会实时显示每个应用的连接池状态任何异常波动都会触发告警。