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

MySQL 導致 CPU 100% 根因排查:長連線洩漏、慢查詢與連線池配置實戰

     編輯:MySQL 資料庫相關知識

案例現場

  • 環境:Linux AS4 + PHP 5 + MySQL 5 + Apache 2
  • 現象:top 顯示 mysqld CPU 長期 100%
  • 排除:DDoS、系統負載、硬體故障

根因定位

-- 1. 查看當前連線與執行緒
SHOW PROCESSLIST;
-- 發現大量 Sleep 狀態連線(數百個)

-- 2. 檢查 PHP 代碼
// 錯誤模式:只有 mysql_connect(),無 mysql_close()
$link = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('db');
// 執行查詢...
// 缺少 mysql_close($link);

解決方案

  1. 補全關閉連線:所有 PHP 腳本結束執行 mysql_close()
  2. 改用持久連線:mysql_pconnect() 複用連線,但需配合 wait_timeout 管理
  3. 配置連線池:PHP-FPM / Apache mod_php 配置最大連線數

驗證效果

修復後 CPU 從 100% 降至 1%~10% 正常區間。

MySQL 核心函數速查(PHP mysql_* 擴展已棄用,建議 PDO/MySQLi)

系統級排查清單

函數用途替代
mysql_connect建立連線mysqli_connect / new PDO
mysql_pconnect持久連線mysqli_pconnect / PDO::ATTR_PERSISTENT
mysql_close關閉連線mysqli_close / $pdo = null
mysql_query執行查詢mysqli_query / $pdo->query
mysql_fetch_assoc取關聯陣列mysqli_fetch_assoc / $stmt->fetch(PDO::FETCH_ASSOC)
mysql_real_escape_string跳脫字串mysqli_real_escape_string / 預處理
mysql_insert_id取自增 IDmysqli_insert_id / $pdo->lastInsertId
mysql_affected_rows影響行數mysqli_affected_rows / $stmt->rowCount
mysql_errno/error錯誤碼/訊息mysqli_errno/error / $pdo->errorInfo
mysql_free_result釋放結果集mysqli_free_result / 無需(PDO 自動)

最佳實踐總結

  1. 應用層:務必關閉連線,使用預處理語句,避免 N+1 查詢
  2. 連線池:設定 max_connections、wait_timeout、interactive_timeout 合理值
  3. 監控:部署 Prometheus + mysqld_exporter + Grafana 監控儀表板
  4. 慢查詢:長期開啟 long_query_time=1,定期 pt-query-digest 分析
  5. 升級:PHP 7.4+ + MySQLi/PDO,棄用 mysql_* 擴展
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
層面指令/工具關鍵指標
OStop, vmstat, iostat, pidstatCPU 使用率、上下文切換、IO wait
MySQL 連線SHOW PROCESSLIST; SHOW STATUS LIKE 'Threads%';Sleep 連線數、活躍查詢、等待鎖
慢查詢pt-query-digest / mysqldumpslow高頻慢 SQL、全表掃描、臨時表
InnoDB 狀態SHOW ENGINE INNODB STATUS鎖等待、死鎖、Buffer Pool 命中率
配置參數SHOW VARIABLESmax_connections、wait_timeout、innodb_buffer_pool_size