萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL "Too many connections" 錯誤完整排查與優化

MySQL 連接數耗盡 (Error 1040) 根因分析與解決方案

Too many connections 表示當前連接數達到 max_connections 上限。核心影響因子:max_connections 設定值、wait_timeout 空閒釋放時間、應用連接池洩漏、慢查詢堵塞。

錯誤代碼與現象

  • 錯誤號:1040 (ER_CON_COUNT_ERROR)
  • 新連接被拒,現有連接正常
  • 應用拋出 SQLState: 08004

即時緩解:調大 max_connections

Windows (my.ini)

[mysqld]
max_connections = 1000
wait_timeout = 60
interactive_timeout = 60

Linux (my.cnf)

[mysqld]
max_connections = 1000
wait_timeout = 60

修改後 必須重啟 MySQL 生效:systemctl restart mysqld 或 net restart mysql。

MySQL 5.1+ 動態調整 (無需重啟)

SET GLOBAL max_connections = 1000;
SET GLOBAL wait_timeout = 60;
-- 注意:重啟後失效,需同步修改配置檔

根因深度排查

1. 查看當前連接狀態

SHOW PROCESSLIST;
-- 或詳細版
SELECT * FROM information_schema.PROCESSLIST 
WHERE COMMAND != 'Sleep' ORDER BY TIME DESC;

2. 統計連接來源

SELECT 
    SUBSTRING_INDEX(host, ':', 1) AS client_ip,
    COUNT(*) AS conn_count,
    GROUP_CONCAT(DISTINCT COMMAND) AS cmds,
    GROUP_CONCAT(DISTINCT STATE) AS states
FROM information_schema.PROCESSLIST
GROUP BY client_ip ORDER BY conn_count DESC;

3. 發現 Sleep 連接過多 → 應用連接池洩漏

  • Java: HikariCP/Druid 設定 maxLifetime、idleTimeout
  • Python: SQLAlchemy pool_recycle、pool_pre_ping
  • PHP: mysqli/pdo 確保正確 close、persistent 連接慎用
  • Go: sql.DB SetMaxIdleConns、SetConnMaxLifetime

4. 發現慢查詢堵塞 → SQL 優化

-- 開啟慢查詢日誌
SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 1;
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

架構層面優化

層面措施
應用層連接池適度大小、啟用連接驗證、縮短超時
Proxy 層ProxySQL/MaxScale 連接多工、讀寫分離
資料庫層thread_pool (Percona/Enterprise)、調整 thread_cache_size
架構層讀寫分離、分庫分表、快取層 (Redis) 卸載讀流量

容量規劃公式

max_connections ≈ (CPU核心數 * 2~4) + (預期並發業務連接數 * 1.5)
-- 典型 8核生產環境:300~500 較合理,1000 需評估記憶體
-- 每連接約 256KB~2MB 記憶體 (依 sort_buffer、join_buffer 等)

虛擬主機/受管環境

無法修改配置時:

  • 聯繫服務商調整配置
  • 優化應用連接池參數
  • 引入連接池中間件 (ProxySQL)
  • 升級方案獲取更高配額
copyright © 萬盛學電腦網 all rights reserved