萬盛學電腦網

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

MySQL Sleep 進程過多導致卡頓:根因分析與 wait_timeout 優化實戰

現象

SHOW PROCESSLIST 大量 Sleep 狀態連接佔據 max_connections,新請求報「Too many connections」,服務器 CPU/內存飆升甚至崩潰。

根因分析

  1. PHP 未顯式關閉連接:腳本結束不會自動斷開 MySQL 連接(Session 等資源更不會),必須調用 mysqli_close() 或 PDO=null。
  2. 持久連接 (pconnect) 濫用:長連接復用導致閒置連接堆積,高併發下反而耗盡連接池。
  3. 慢查詢阻塞:SQL 執行時間過長,連接佔用時間延長,間接導致併發連接數上升。

立竿見影的緩解方案:縮短超時自動斷開

修改 my.cnf / my.ini

[mysqld]
# 非交互式連接(應用程序)閒置超過 100 秒自動斷開
wait_timeout = 100

# 交互式連接(客戶端工具)閒置超時
interactive_timeout = 100
  • 默認 28800 秒 (8 小時),極易積壓無效連接。
  • 建議值:30~300 秒,視業務閒置特性調整。

重啟生效

service mysqld restart
# 或 Windows
net stop mysql && net start mysql

配合調優內存參數(釋放緩存壓力)

[mysqld]
# 降低表緩存與定義緩存,減少內存佔用
table_open_cache = 256          # 原 2000
table_definition_cache = 400    # 原 1400
  • 小內存機器(<4GB)或連接數大時,適當降低可緩解 OOM 風險。
  • 監控 Opened_tables / Open_tables 比值調整。

根治方案(開發層面)

  1. 強制關閉連接:框架層統一在請求結束調用 close(),或使用連接池(HikariCP/Druid)配置 maxLifetime、idleTimeout。
  2. 禁用 pconnect:高併發場景改用短連接+連接池。
  3. 慢 SQL 優化:開啟 slow_query_log,EXPLAIN 分析加索引、改寫 SQL,降低單查詢耗時。
  4. 監控告警:Prometheus + Grafana 監控 Threads_connected、Threads_running、Aborted_connects,閾值告警。

驗證效果

mysql> SHOW GLOBAL STATUS LIKE 'Threads_connected';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_connected | 15    |  -- 大幅下降
+-------------------+-------+

配置生效後,Sleep 進程數顯著下降,連接池穩定,服務器負載恢復正常。

copyright © 萬盛學電腦網 all rights reserved