首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL "Too many connections" 連接數耗盡完整排查與優化指南

     編輯:MySQL 資料庫相關知識

錯誤 ERROR 1040 (HY000): Too many connections 表示當前活躍連接數達到 max_connections 上限。本文系統講解連接數監控、參數調優、連接池配置、應用層洩漏排查、緊急擴容五大維度,徹底解決連接耗盡問題。

一、 核心機制與關鍵變量

變量含義默認值最大值動態修改
max_connections服務器允許的最大並發連接數151 (5.7+) / 100 (舊版)100000 (實際受 OS 文件描述符限制 ~65535)✅ SET GLOBAL
threads_connected當前打開的連接數 (即時)--只讀
max_used_connections啟動以來峰值並發連接數--只讀
connection_errors_max_connections因達上限被拒絕的連接嘗試次數--只讀

二、 實時監控與診斷

-- 1. 查看當前配置與狀態
SHOW VARIABLES LIKE 'max_connections';
SHOW GLOBAL STATUS LIKE 'threads_connected';
SHOW GLOBAL STATUS LIKE 'max_used_connections';
SHOW GLOBAL STATUS LIKE 'connection_errors_max_connections';

-- 2. 連接來源分析
SHOW PROCESSLIST;
-- 或詳細版
SELECT * FROM information_schema.PROCESSLIST ORDER BY TIME DESC;

-- 3. 按用戶/主機統計
SELECT USER, HOST, COUNT(*) AS conn_count
FROM information_schema.PROCESSLIST
GROUP BY USER, HOST
ORDER BY conn_count DESC;

三、 參數調優:調大 max_connections

1. 動態生效 (無需重啟)

SET GLOBAL max_connections = 3000;

2. 持久化配置 (my.cnf / my.ini)

[mysqld]
max_connections = 3000
# 相關配套調大
open_files_limit = 10000          # OS 文件描述符上限,需 ulimit -n 支援
table_open_cache = 2000           # 表緩存,防止頻繁開關表
max_user_connections = 2000       # 單用戶上限,防單點佔用

3. OS 級限制同步修改 (/etc/security/limits.conf)

mysql soft nofile 65535
mysql hard nofile 65535

重啟 MySQL 服務生效。

四、 根因分類與對應策略

根因類別典型特徵排查方法解決策略
配置過小業務增長、max_connections 仍為默認 151max_used_connections 接近上限、業務正常調大 max_connections、配套調大 open_files_limit
連接洩漏 (應用 Bug)連接數單調遞增、不釋放、最終耗盡threads_connected 持續增長、SHOW PROCESSLIST 顯示大量 Sleep 狀態、同一應用節點連接數異常代碼審查:確保 try-finally/using 關閉連接、連接池 maxWait/maxIdle 配置合理
連接池配置不當池大小 > max_connections、或未限制最大池尺寸應用啟動後連接數迅速達上限連接池 maxPoolSize ≤ max_connections / 應用實例數,預留管理連接
慢查詢堵塞長事務佔用連接、新請求排隊SHOW PROCESSLIST 顯示大量 Time 大、State=Sending data/Locked優化慢 SQL、設置 max_execution_time、殺死長事務
攻擊/爬蟲大量異常 IP/用戶建立連接PROCESSLIST 顯示大量未知來源、connection_errors_max_connections 飆升防火牆限制 IP、WAF 防護、max_user_connections 限制單用戶

五、 連接池最佳配置 (以 HikariCP / Druid / DBCP2 為例)

# HikariCP (Spring Boot 2+ 默認)
spring.datasource.hikari.maximum-pool-size=20        # 單實例池大小
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=300000         # 5分鐘空閒回收
spring.datasource.hikari.max-lifetime=1800000        # 30分鐘強制換新
spring.datasource.hikari.connection-timeout=30000    # 獲取連接超時 30s
spring.datasource.hikari.leak-detection-threshold=60000 # 洩漏檢測 60s

原則: 總池大小 (實例數 × maximum-pool-size) ≤ max_connections × 80% (預留 20% 給管理/備份/監控連接)。

六、 緊急臨時擴容腳本 (不重啟)

#!/bin/bash
# 緊急將 max_connections 臨時調大至 5000
mysql -uroot -p -e "SET GLOBAL max_connections = 5000;"
# 同步調大 open_files_limit (需重啟生效,這裡僅作提醒)
echo "WARNING: open_files_limit needs restart. Current: $(mysql -uroot -p -e 'SHOW VARIABLES LIKE \"open_files_limit\";' -sN | awk '{print $2}')"
# 觀察 10 分鐘
sleep 600
# 恢復原值 (視情況)
# mysql -uroot -p -e "SET GLOBAL max_connections = 3000;"

七、 總結

Too many connections 不是病,是症狀。 核心動作三步走:

  1. 監控定基線: 記錄 max_used_connections 日峰值,配置 max_connections = 峰值 × 1.5~2。
  2. 連接池守門: 應用層嚴格限制池大小、空閒回收、洩漏檢測,杜絕「佔著茅坑不拉屎」的長連接。
  3. 慢查詢清道夫: 定期 pt-query-digest 分析慢日誌,優化 Top 10 慢 SQL,釋放被堵塞的連接。

建立連接數告警規則 (threads_connected / max_connections > 80% 觸發),配合自動擴容腳本,實現從「救火」到「防火」的轉變。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved