ERROR 1040 (HY000): Too many connections
應用日誌大量拋出數據庫連接失敗異常,業務請求超時或報 500。
| 指標 | 含義 | 默認值 | 理論上限 |
|---|---|---|---|
max_connections |
服務端允許的最大並發連接數 | 151 (MySQL 5.7+) | 16384 |
threads_connected |
當前已建立的連接數(含睡眠連接) | 動態變化 | ≤ max_connections |
Threads_running |
當前正在執行查詢的線程數 | 動態變化 | ≤ threads_connected |
觸發條件:threads_connected == max_connections 時,新連接請求被拒絕。
mysql> SHOW VARIABLES LIKE 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 151 |
+-----------------+-------+
mysql> SHOW STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_connected | 151 |
+-------------------+-------+
或持續監控:watch -n 1 'mysql -e "SHOW STATUS LIKE \"Threads_connected\""'mysql> SELECT host, user, COUNT(*) AS cnt,
SUM(IF(command='Sleep',1,0)) AS sleep_cnt
FROM information_schema.processlist
GROUP BY host, user
ORDER BY cnt DESC;
重點關注 Sleep 佔比高的客戶端 IP,通常為連接泄漏或連接池配置不當。現象:業務增長導致並發超過默認 151。
對策:修改配置文件 my.cnf:
[mysqld]
max_connections = 3000 # 根據機器內存與業務峰值評估,建議不超過 8000
重啟生效。注意:每個連接約消耗 256KB-2MB 內存(取決於 sort_buffer_size、join_buffer_size 等),3000 連接約需 1-4GB 額外內存,確保機器內存充足。
現象:Sleep 連接佔比 > 80%,且隨時間單調增長。
對策:
try-with-resources / finally 中關閉 Connection、Statement、ResultSet。validationQuery + testOnBorrow / testWhileIdle,配合 timeBetweenEvictionRunsMillis 定期清理空閒連接。maxIdle、minIdle、maxWait,避免池無限增長。現象:Threads_running 持續偏高,SHOW PROCESSLIST 顯示大量 Time 較大的查詢。
對策:
innodb_lock_wait_timeout、net_read_timeout、net_write_timeout 防止連接長期阻塞。performance_schema 或 sys schema 監控事務執行時間,超時自動殺死。現象:秒殺、定時任務並發啟動導致瞬間連接數飆升。
對策:
max_connections 較大值 + back_log 增大(如 2000),緩衝瞬間衝擊。現象:即使調大 max_connections,連接數仍卡在 1024 或 4096。
對策:
# /etc/security/limits.conf
mysql soft nofile 65535
mysql hard nofile 65535
# /etc/sysctl.conf
fs.file-max = 1000000
重啟 MySQL 服務生效。
[mysqld]
# 連接數
max_connections = 5000
back_log = 2000
# 連接超時清理
wait_timeout = 28800 # 8小時無活動斷開
interactive_timeout = 28800
net_read_timeout = 30
net_write_timeout = 60
# 緩衝區控制(減少單連接內存佔用)
sort_buffer_size = 256K
join_buffer_size = 256K
read_buffer_size = 128K
read_rnd_buffer_size = 256K
# 安全
max_connect_errors = 100000
skip_name_resolve = 1
Threads_connected / max_connections > 80% 觸發預警,> 95% 觸發嚴重告警。mysql_global_status_threads_connected、mysql_global_variables_max_connections、mysql_global_status_threads_running、mysql_global_status_aborted_connects。「Too many connections」 絕非單純調大 max_connections 即可解決,需建立 「配置調優 + 連接池治理 + SQL優化 + 限流熔斷 + 監控告警」 的全鏈路治理體系。優先排查連接泄漏與慢查詢,再評估是否真需要擴大 max_connections,避免因內存不足導致 OOM Killer 殺死 MySQL 進程,造成更嚴重的服務不可用。