天天看點

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

前言

判斷查詢的性能就是看查詢執行的時間,這個時間針對不同的業務要求上也有差異。在同一時間内SQL執行的越快,執行的SQL就越多,完成的業務邏輯就越多。同樣一個業務場景不同的架構設計、資料庫表索引設計,由不同的人來做效果是不同的,有的人可以用很低的成本,RDS規格,ECS規格跑出很高的性能。最好的情況是自頂向下了解業務,以及每個業務涉及的SQL,這樣就能厘清業務和資料庫負載的關系;也能找到短闆,并對短闆做有針對性的優化;全鍊路壓測就是做的這個事情。另外也可以借鑒xtrace,strace等理念在分布式環境中做全鍊路的監控,阿裡雲已經有這樣的産品叫鍊路追蹤,可以清楚地監控從應用元件到基礎元件,哪一個環節耗時最長,哪一個環節報錯,詳細請參考文檔 

https://www.aliyun.com/product/xtrace

。全鍊路監控和全鍊路壓測是值得大多數系統學習的。

下面針對資料庫的各種導緻SQL慢的排查思路,原因和解決方法進行闡述:

執行個體達到瓶頸

如果監控比較細微或對響應時間比較敏感的話,瓶頸很容易被監控到,達到瓶頸時一般可能有以下幾種因素:

  1. 随着業務的增長而沒有擴容,總有那麼一天系統變慢;
  2. 随着時間的變化,大量的磁盤擦寫或快過保的機器性能有損耗,也會達到瓶頸;
  3. 随着時間的累計,資料隻增加不清理,表的大小也不斷增加,有可能原來不慢的SQL變慢,如:索引缺失;可以借助自治服務診斷。

控制台路徑是選擇“雲資料庫RDS”->選擇“執行個體清單”->點選執行個體連結,進入執行個體頁面->選擇“自治服務”->選擇“資源監控”,詳細參考

https://help.aliyun.com/document_detail/95667.html

。如果資源使用使用率各項名額都100%,可能是執行個體達到了瓶頸,這時候建議更新執行個體規格,方法參考

https://help.aliyun.com/document_detail/96061.html

判斷執行個體有沒有達到瓶頸,比較好的方法是先找到執行個體的性能基準值,先用sysbench或其他測試工具建構基準測試,當不管怎麼增加壓力,資料庫的性能再也上不去時說明基準值已經出來了,在複雜場景下的QPS/TPS響應時間很少會超過基準值的。

版本升降級

資料庫的版本更新可能會導緻SQL執行計劃發生改變,執行計劃查詢類型依次從好到壞的順序是“system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > all”(官方連結

https://dev.mysql.com/doc/refman/5.6/en/explain-output.html#explain-join-types

),查詢類型從“range -> index”,因為SQL的請求變慢,業務又不斷重試請求,導緻SQL并行查詢比較多,進而影響應用線程釋放慢,導緻應用連接配接池耗盡,影響整個業務。檢視近期有沒有修改過參數的控制台路徑是選擇“雲資料庫RDS”->選擇“曆史事件”,詳細參考

https://help.aliyun.com/document_detail/131008.html

,如下圖所示:

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

參數調整

參數buffer_pool_instances/join_buffer_size/AHI等的變化也會導緻性能變慢。關于這方面的文章比較多,這裡不一一贅述。檢視近期有沒有修改過參數的控制台路徑是選擇“雲資料庫RDS”->選擇“執行個體清單”->點選執行個體連結,進入執行個體頁面->選擇“參數設定”->選擇“修改曆史”,詳細參考

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

緩存失效

緩存的設計在架構上很好地承擔了大量的查詢,但并不能保證緩存命中率100%,如果緩存失效,也會有大量的查詢湧到資料庫端,導緻性能下降。從資料庫表現來說,看到各方面的資源(通常是CPU)打滿,QPS/活躍線程飙的非常高。這樣的情況RDS MySQL可以用SQL限流、打開線程池、語句并行隊列、Fast Query Cache等可以緩解,詳情參考

https://help.aliyun.com/document_detail/130306.html

。目前資料庫自治服務DAS,可以提供自動調參/自動擴容/SQL自動優化/SQL自動限流的工作,詳情參考

https://help.aliyun.com/document_detail/164859.html

批量操作

如果有大批量的資料導入、删除、或拖資料的情況。

批量資料導入 

這種情況可以從磁盤空間,或SQL洞察/慢查詢裡找到對應語句。如從binlog的大小,正常情況每個binlog問卷大小是500MB,如果有超過500MB的,就可以看是否有異常情況。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

也可以從監控上看哪部分的空間有變化。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

如果有批量資料導入IOPS上也會增加。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

事務數也會增加。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

InnoDB的寫入量也會增加。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

日志檔案的寫入也會增加。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

InnoDB層的寫入也會增加。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

批量資料删除/回收

這種情況可以從磁盤空間,或SQL洞察/慢查詢裡找到對應語句。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結
【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結
【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

可以看到truncate table時select 1都很慢。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

拖資料

這種情況可以通過監控名額的變化或SQL洞察/慢查詢裡找到對應語句。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結
【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

未關閉的事務

如果某個任務突然變慢,應該考慮是否有鎖阻塞的問題。可以通過“如何定位長時間未關閉的事務和處理方法”這篇文章找到未釋放的鎖,應通過更快地釋放鎖來改善。如下圖CPU和IOPS的使用率并不高,但應用擁堵,MySQL的活躍會話上漲就是存在未關閉的事務導緻的。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

未送出事務:

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

定時任務

如果負載随時間有規律性變化,則瓶頸随負載有規律性地變化,很大可能是定時任務引起的,如圖所示:

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

SQL異常

查詢慢有很多種原因導緻,這種情況可能是由于庫表結構設計不合理,或索引缺失,或掃描行數太多,或不常用到的查詢條件導緻,這種情況需要開發人員修改。

影響SQL語句執行的因素大概分為以下幾類:表有哪些索引、存儲特性、資料庫引擎特性、查詢條件的區分度、結果集大小、表的資料量、CPU時間。關于這一點已經講的比較多,詳細可以參考阿裡雲資料庫最佳實踐

https://yq.aliyun.com/live/1938

此外還可以使用資料庫自治服務優化慢SQL,可參考

https://help.aliyun.com/document_detail/167895.html

業務場景發生改變

如何确定業務場景發生了改變呢?有兩種可能:

1. 應用進行過釋出 

應用有沒有進行過釋出,需要看下應用的部署日志或釋出系統可以查到痕迹。

2. 沒釋出,功能早上線,但不經常用,某天使用者點了某個功能。

如果想确切定位同時段的SQL是否一樣,就需要打開審計日志。打開審計日志的方法參考文檔

https://help.aliyun.com/document_detail/96123.html

。同時段的SQL可以跟昨天同時間對比,或上周同時間對比。借助SQL洞察的SQL分析功能,或者更友善地用DAS專業版的“SQL對比”/“來源統計”。發現和沒有問題時間段的SQL,找到來源即可。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

或用DAS資料庫自治服務的"一鍵診斷",路徑參考

https://help.aliyun.com/document_detail/99478.html
【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

掃描行數多

路徑位址:阿裡雲控制台->選擇對應資料庫引擎->找到對應執行個體,點選“執行個體ID/名稱”->選擇“SQL洞察”或“自治服務”裡的“慢SQL”

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

多表join

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

索引不合理

例如:

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

全表掃描

全表掃描一般發生在索引不合理或沒有WHERE條件的SQL語句中,索引不合理好解決建立合适的索引就可以了,但對于沒有WHERE條件的SQL語句發生時可以kill或降級業務解決。沒有WHERE條件但SQL語句是高風險SQL,建議分批執行或放在業務低峰期執行,當然了盡量帶上WHERE條件。如下圖就是不帶WHERE條件的,在DAS控制台/慢查詢/SQL洞察等都可以找到。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

CPU達到瓶頸

CPU在系統中相當于大腦,當CPU達到瓶頸後排程IO等就慢,也會導緻慢SQL産生,這種情況可以從監控名額上看出。如

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

IO慢

IOPS達到瓶頸 

如果慢SQL裡出現DML,很大程度是IOPS使用率較高,如:

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

可以從SQL洞察裡找到慢SQL:

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

也可從慢日志明細看到:

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結
【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

刷髒導緻的IO慢

MySQL觸發刷髒的時機有:RedoLog滿,記憶體不夠用,記憶體刷髒過程中的額外開銷。這種情況可能會觸發Buffer Pool的鎖

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

業務場景發生變化

業務進行過釋出,或有不經常通路的業務突發通路比如ad-hoc類等,從監控名額上可以看到異常。

【巡檢問題分析與最佳實踐】RDS MySQL慢SQL問題前言執行個體達到瓶頸版本升降級參數調整緩存失效批量操作未關閉的事務定時任務SQL異常CPU達到瓶頸IO慢業務場景發生變化總結

總結

哪些可以幫助我們定位慢SQL?

  • 監控名額

對比兩個時間段的監控名額的差異,如資源層面的差異,引擎層面的差異,選擇“雲資料庫RDS”->選擇“執行個體清單”->點選執行個體連結,進入執行個體頁面->選擇“監控與報警”->選擇“資源監控”/“引擎監控”,下面看下各個名額的含義:

監控項 含義 說明
磁盤空間 執行個體的磁盤空間占用曆史趨勢,機關GB
IOPS RDS執行個體的IOPS(每秒IO請求次數)
連接配接數 目前總連接配接數
CPU使用率 RDS執行個體CPU使用率(占作業系統總數)
網絡流量 MySQL執行個體平均每秒鐘的輸入、輸出流量,機關為KB
QPS/TPS 每秒鐘SQL語句執行次數和事務處理數
InnoDB緩存讀命中率、使用率、髒塊率 InnoDB緩沖池的讀命中率、使用率以及緩沖池髒塊的百分率
InnoDB讀寫量 InnoDB平均每秒讀取和寫入的資料量
InnoDB讀寫次數 InnoDB每秒鐘的讀取和寫入的次數
InnoDB日志 InnoDB的日志寫入情況
MySQL執行語句時在硬碟上自動建立的臨時表的數量 執行語句時在硬碟上自動建立的臨時表的數量
MyISAM Key Buffer MyISAM平均每秒的Key Buffer使用狀況
MyISAM讀寫次數 MyISAM平均每秒的讀寫次數
MySQL_COMDML 資料庫每秒SQL語句執行次數,包括的類型如下:Insert、Delete、Insert_Select、Replace、Replace_Select、Select、Update
MySQL_RowDML InnoDB每秒鐘操作執行次數,包括:
  • 每秒向日志檔案的實體寫次數
  • 每秒從 InnoDB 表讀取、更新、删除、插入的行數
  • 慢日志
  • SQL洞察
  • 資料庫自治服務

因為上面已經有路徑或幫助文檔,這裡不再贅述。在實際業務場景中情況可能會比上面提到的情況複雜的多,有可能是多種情況的疊加,不過排查問題的思路是一緻的,希望上述方法對您有幫助。