報錯 ERROR 1040 (HY000): Too many connections 時,實際觸發條件為:
threads_connected >= max_connections
兩大根因:
max_connections=151 (5.7+) / 100 (舊版) 遠低於現代並發需求。-- 當前連線數
SHOW STATUS LIKE 'Threads_connected';
-- 歷史峰值
SHOW STATUS LIKE 'Max_used_connections';
-- 配置上限
SHOW VARIABLES LIKE 'max_connections';
-- 詳細連線來源
SHOW PROCESSLIST;
-- 或
SELECT * FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep';
SET GLOBAL max_connections = 5000; -- 視記憶體而定,建議 ≤ 10000
持久化需同步修改 my.cnf:
[mysqld]
max_connections = 5000
| 參數 | 建議值 (以 5000 連線為例) | 說明 |
|---|---|---|
open_files_limit | 65535 | OS 級限制,ulimit -n 同步修改 |
table_open_cache | 4000 | 約 max_connections * 0.8 |
innodb_buffer_pool_size | 物理記憶體 60-70% | 核心緩衝,防磁碟 I/O 瓶頸 |
thread_cache_size | 100 | 減少線程創建銷毀開銷 |
back_log | 500 | TCP 連線隊列 |
pool_size = (CPU核心數 * 2) + 有效磁碟數,不可無限增大。wait_timeout=300、interactive_timeout=300 清理閒置連線。try-finally / using 關閉連線;異常拋出前釋放資源。mysql_global_status_threads_connected / mysql_global_variables_max_connections > 0.8 觸發告警。「把 max_connections 設成 10 萬就萬事大吉」
❌ 每個連線佔用 thread_stack (256KB) + sort_buffer/join_buffer/read_buffer 等執行緒緩衝,10 萬連線需數十 GB 記憶體,極易觸發 OOM Killer。實際上限受限於 open_files_limit 與 OS 文件描述符,通常 1-2 萬為物理極限。
「配置給上限,應用守底線,監控拉警報」 三管齊下。先用 SET GLOBAL 救火,再調優參數矩陣,最後在代碼層徹底堵住洩漏,才是持久之計。