背景
線上mysql服務器經常性出現cpu使用率100%的告警, 因此整理一下排查該問題的常規流程。
1. 確認CPU占用來源
- 檢查系統進程
使用top
或htop
命令,確認是否是mysqld
進程導致CPU滿載:top -c -p $(pgrep mysqld)
2. 實時分析MySQL活動
- 查看當前運行的SQL
登錄MySQL,執行以下命令,觀察是否有長時間運行或高頻率的查詢:SHOW FULL PROCESSLIST; -- 或過濾非空閑連接 SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE COMMAND != 'Sleep' AND TIME > 0;
- 終止問題查詢
若發現異常查詢,可通過KILL [PROCESS_ID]
終止。
3. 分析慢查詢與執行計劃
-
啟用慢查詢日志
在MySQL配置文件(my.cnf
/my.ini
)中啟用慢查詢日志:slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 -- 閾值(秒)
重啟MySQL后,使用
mysqldumpslow
或pt-query-digest
分析日志。 -
使用
EXPLAIN
分析SQL
對可疑查詢添加EXPLAIN
,檢查是否缺少索引或全表掃描:EXPLAIN SELECT * FROM your_table WHERE your_condition;
4. 檢查索引與表結構
- 索引缺失
通過SHOW CREATE TABLE
檢查表結構,確保高頻查詢字段有索引。 - 冗余索引
使用pt-duplicate-key-checker
工具刪除無效索引。 - 統計信息過時
執行ANALYZE TABLE your_table;
更新統計信息。
5. 排查鎖爭用與事務
- 查看當前鎖狀態
SHOW ENGINE INNODB STATUS; -- 查看LATEST DETECTED DEADLOCK SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX; -- 運行中的事務 SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS; -- 當前持有的鎖
- 長事務處理
終止未提交的長事務或優化事務代碼。
6. 檢查MySQL配置
- 關鍵參數調優
innodb_buffer_pool_size
:建議設置為物理內存的70%-80%。max_connections
:避免過高導致資源爭用。tmp_table_size
和max_heap_table_size
:減少磁盤臨時表。
- 連接數監控
SHOW STATUS LIKE 'Threads_connected'; -- 當前連接數 SHOW VARIABLES LIKE 'max_connections'; -- 最大允許連接數
7. 系統資源與硬件瓶頸
- 內存與交換分區
使用free -h
或vmstat
檢查內存是否不足,導致頻繁Swap。 - 磁盤I/O
使用iostat
或iotop
查看磁盤負載,優化高I/O操作(如批量寫入、索引重建)。 - CPU架構
確認是否因并發線程過多導致CPU爭用(如innodb_thread_concurrency
設置)。
8. 其他可能原因
- 復制問題
主從復制延遲或錯誤可能導致從庫CPU升高,檢查SHOW SLAVE STATUS
。 - 緩存失效
如查詢緩存(query_cache_type
)頻繁失效,考慮關閉。 - 日志寫入壓力
關閉不必要的日志(如通用查詢日志),或調整sync_binlog
參數。
9. 使用專業工具
- 監控工具
Percona Monitoring and Management (PMM)、VividCortex 或 Prometheus + Grafana。 - 性能分析工具
pt-query-digest
、mysqlsla
或 MySQL自帶的Performance Schema
。
快速處理步驟
top
確認MySQL進程導致CPU滿載。SHOW PROCESSLIST
查找異常查詢。EXPLAIN
分析問題SQL,優化索引或查詢邏輯。- 終止阻塞進程(
KILL
)或重啟MySQL(臨時恢復)。
通過以上步驟,多數情況下可以定位到CPU過高的根本原因,如慢查詢、索引缺失、配置不當或硬件瓶頸,進而針對性優化。若問題復雜,建議結合監控工具長期跟蹤分析。
最后
歡迎點擊關注gzh: 加瓦點燈,不錯過每一次的干貨!