MySQL CPU 使用率高的原因和解決方法


用戶在使用 MySQL 實例時,會遇到 CPU 使用率過高甚至達到 100% 的情況。本文將介紹造成該狀況的常見原因以及解決方法,並通過 CPU 使用率為 100% 的典型場景,來分析引起該狀況的原因及其相應的解決方案。

常見原因

系統執行應用提交查詢(包括數據修改操作)時需要大量的邏輯讀(邏輯 IO,執行查詢所需訪問的表的數據行數),所以系統需要消耗大量的 CPU 資源以維護從存儲系統讀取到內存中的數據一致性。

說明:大量行鎖沖突、行鎖等待或后台任務也有可能會導致實例的 CPU 使用率過高,但這些情況出現的概率非常低,本文不做討論。

本文通過一個簡化的模型來說明系統資源、語句執行成本以及 QPS(Query Per Second 每秒執行的查詢數)之間的關系:

  • 條件:應用模型恆定(應用沒有修改)。

  • avg_lgc_io:執行每條查詢需要的平均邏輯 IO。

  • total_lgc_io:實例的 CPU 資源在單位時間內能夠處理的邏輯 IO 總量。

  • 關系公式:total_lgc_io = avg_lgc_io x QPS -- 單位時間 CPU 資源 = 查詢執行的平均成本 x 單位時間執行的查詢數量

解決方法

數據管理(DMS)工具提供了幾種輔助排查並解決實例性能問題的功能,主要有:

  • 實例診斷報告

  • SQL 窗口提供的查詢優化建議和查看執行計划

  • 實例會話

其中,實例診斷報告是排查和解決 MySQL 實例性能問題的最佳工具。無論何種原因導致的性能問題,建議您首先參考下實例診斷報告,尤其是診斷報告中的 SQL 優化、會話列表和慢 SQL 匯總分。

另外,如果您需要阿里雲的技術支持來解決 CPU 使用率高的狀況,請參見 https://market.aliyun.com/store/1682301.html

避免出現 CPU 使用率達到 100% 的一般原則

  • 設置 CPU 使用率告警,實例 CPU 使用率保證一定的冗余度。

  • 應用設計和開發過程中,要考慮查詢的優化,遵守 MySQL 優化的一般優化原則,降低查詢的邏輯 IO,提高應用可擴展性。

  • 新功能、新模塊上線前,要使用生產環境數據進行壓力測試(可以考慮使用阿里雲 PTS 壓力測試工具)。

  • 新功能、新模塊上線前,建議使用生產環境數據進行回歸測試。

  • 建議經常關注和使用 DMS 中的診斷報告。

    注意:關於如何訪問 DMS 中的診斷報告,請參見 RDS 如何訪問診斷報告

典型示例

以 CPU 使用率為 100% 的典型場景為例,本文介紹了兩個引起該狀況的原因及其解決方案,即應用負載(QPS)高和查詢執行成本(查詢訪問表數據行數 avg_lgc_io)高。其中,由於查詢執行成本高(查詢訪問表數據行數多)而導致實例 CPU 使用率高是 MySQL 非常常見的問題。

應用負載(QPS)高

現象描述

  • 特征:實例的 QPS(每秒執行的查詢次數)高,查詢比較簡單、執行效率高、優化余地小。

  • 表現:沒有出現慢查詢(或者慢查詢不是主要原因),且 QPS 和 CPU 使用率曲線變化吻合。

  • 常見場景:該狀況常見於應用優化過的在線事務交易系統(例如訂單系統)、高讀取率的熱門 Web 網站應用、第三方壓力工具測試(例如 Sysbench)等。

解決方案

對於由應用負載高導致的 CPU 使用率高的狀況,使用 SQL 查詢進行優化的余地不大,建議您從應用架構、實例規格等方面來解決,例如:

  • 升級實例規格,增加 CPU 資源。

  • 增加只讀實例,將對數據一致性不敏感的查詢(比如商品種類查詢、列車車次查詢)轉移到只讀實例上,分擔主實例壓力。

  • 使用阿里雲 DRDS 產品,自動進行分庫分表,將查詢壓力分擔到多個 RDS 實例上。

  • 使用阿里雲 Memcache 或者雲 Redis 產品,盡量從緩存中獲取常用的查詢結果,減輕 RDS 實例的壓力。

  • 對於查詢數據比較靜態、查詢重復度高、查詢結果集小於 1 MB 的應用,考慮開啟查詢緩存(Query Cache)。

    注意:能否從開啟查詢緩存(Query Cache)中獲益需要經過測試,具體設置請參見 RDS for MySQL 查詢緩存(Query Cache)的設置和使用

  • 定期歸檔歷史數據、采用分庫分表或者分區的方式減小查詢訪問的數據量。

  • 盡量優化查詢,減少查詢的執行成本(邏輯 IO,執行需要訪問的表數據行數),提高應用可擴展性。

查詢執行成本(查詢訪問表數據行數 avg_lgc_io)高

現象描述

  • 特征:實例的 QPS(每秒執行的查詢次數)不高;查詢執行效率低、執行時需要掃描大量表中數據、優化余地大。

  • 表現:存在慢查詢,QPS 和 CPU 使用率曲線變化不吻合。

  • 原因分析:由於查詢執行效率低,為獲得預期的結果即需要訪問大量的數據(平均邏輯 IO高),在 QPS 並不高的情況下(例如網站訪問量不大),就會導致實例的 CPU 使用率高。

解決方案

解決該狀況的原則是:定位效率低的查詢、優化查詢的執行效率、降低查詢執行的成本。

操作步驟
  1. 通過如下方式定位效率低的查詢:

    • 通過 show processlist; 或 show full processlist; 命令查看當前執行的查詢,如下圖所示:

      查看當前執行的查詢

      對於查詢時間長、運行狀態(State 列)是“Sending data”、“Copying to tmp table”、“Copying to tmp table on disk”、“Sorting result”、“Using filesort”等都可能是有性能問題的查詢(SQL)。

      注意:

      • 若在 QPS 高導致 CPU 使用率高的場景中,查詢執行時間通常比較短,show processlist; 命令或實例會話中可能會不容易捕捉到當前執行的查詢。您可以通過執行如下命令進行查詢:

        1. explain select b.* from perf_test_no_idx_01 a, perf_test_no_idx_02 b where a.created_on >= 2015-01-01 and a.detail = b.detail
      • 您可以通過執行類似 kill 101031643; 的命令來終止長時間執行的會話,終止會話請參見 RDS for MySQL 如何終止會話。關於長時間執行會話的管理,請參見 RDS for MySQL 管理長時間運行查詢
    • 通過 DMS 查看當前執行的查詢,查詢步驟如下:

      1. 在 DMS 控制台上登錄數據庫

      2. 選擇性能 > 實例會話,顯示結果如下圖所示:

        DMS 查看執行的查詢

        從上圖可以看出,有 10 個會話在執行下面這個查詢:

        1. select b.* from perf_test_no_idx_01 a, perf_test_no_idx_02 b where a.created_on>= '2015-01-01' and a.detail= b.detail;
      3. 單擊 SQL 列中的查詢文本,即可顯示完整的查詢和其執行計划,如下圖所示:

        查詢詳情

        從上圖可以看出,在該查詢的執行計划中,系統對兩張約為 30 萬行的數據表執行了全表掃描。由於兩張表是聯接操作,這個查詢的執行成本(邏輯 IO)約為 298267 x 298839 = 89,133,812,013(大概 900 億),所以查詢會執行相當長的時間並且多個會話會導致實例 CPU 使用率達到 100%(對於同樣規格的實例,如果是優化良好的查詢,QPS 可以達到 21000;而當前 QPS 僅為 5)。

  2. 得到需要優化的查詢后,可以通過如下任意一種方式來獲取查詢的優化建議:

    • 通過 DMS 的優化查詢獲取:

      注意:對於 QPS 高和查詢效率低的混合模式導致的 CPU 使用率高的問題,建議使用優化查詢獲取優化建議。

      1. 在 DMS 控制台上登錄數據庫

      2. 選擇 SQL 操作 > SQL 窗口。

      3. 單擊優化,即可得到優化建議,如下圖所示:

        優化查詢

    • 通過 DMS 控制台上的診斷報告獲取:

      說明:診斷報告同樣適用於排查歷史實例 CPU 使用率高的問題。

      1. 在 DMS 控制台上登錄數據庫

      2. 選擇性能 > 診斷報告。

      3. 單擊發起診斷,即可創建一個針對當前實例運行情況的報告,如下圖所示:

        診斷報告

      4. 單擊查看報告,查看優化建議。

        注意:對於 CPU 使用率高的問題,建議關注診斷報告的 SQL 優化、會話列表和慢 SQL 匯總部分。

  3. 根據優化建議,添加索引,查詢執行成本就會大幅減少(如下圖所示,從 900 億行減小到 30 萬行,查詢成本降低 30 萬倍),實例 CPU 使用率 100% 的問題解決。

    優化結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM