冷熱數據問題導致SQL執行速度慢
場景描述
從自建MySQL或友商MySQL遷移到云上TaurusDB實例,發現同一條SQL語句執行性能遠差于原數據庫。
原因分析
同一條SQL語句在數據庫中執行第一次和第二次可能會性能差異巨大,這是由數據庫的buffer_pool機制決定的:
- 第一次執行時,數據在磁盤上,稱之為冷數據,讀取需要一定的耗時。
- 讀取完,數據會被存放于內存的buffer_pool中,稱為熱數據,讀取迅速;對于熱數據的訪問速度極大的超過冷數據,所以當數據是熱數據時,SQL語句的執行速度會遠快于冷數據。
該場景中,源端數據庫中常用的數據一般是熱數據,所以訪問時速度極快。當數據遷移到云上TaurusDB時,第一次執行同樣的SQL語句,很可能是冷數據,就會訪問較慢,但再次訪問速度就會得到提升。
解決方案
該場景是正常現象,在同一個數據庫中,我們經常會遇到第一次執行一條語句時很慢,但再次執行就很快,也是因為受到了buffer_pool的冷熱數據原理的影響。
復雜查詢造成磁盤滿
場景描述
主機或只讀節點偶爾出現磁盤占用高或磁盤占用滿,其他只讀節點磁盤空間占用正常。
原因分析
MySQL內部在執行復雜SQL時,會借助臨時表進行分組(group by)、排序(order by)、去重(distinct)、Union等操作,當內存空間不夠時,便會使用磁盤空間。
排查思路:
- 因為其他只讀節點磁盤占用空間正常,且是偶爾出現,說明該實例磁盤占用高,與承載的業務相關。
- 獲取該實例的慢日志,分析磁盤占用高期間,是否有對應的慢SQL。
- 如果有慢SQL,執行 **explain ** [慢SQL語句] ,分析相應慢SQL語句。
- 觀察explain語句輸出的extra列,是否有using temporary、using filesort,如果有,說明該語句用到了臨時表或臨時文件,數據量大的情況下,會導致磁盤占用高。
解決方案
- 復雜查詢語句導致磁盤打滿,建議客戶從業務側優化響應查詢語句,常見優化措施:
- 加上合適的索引。
- 在where條件中過濾更多的數據。
- 重寫SQL,優化執行計劃。
- 如果不得不使用臨時表,那么一定要減少并發度。
- 臨時規避措施:考慮業務側優化復雜查詢語句需要一定時間,可以通過臨時擴容磁盤空間規避。
業務死鎖導致響應變慢
場景描述
14點~15點之間數據庫出現大量行鎖沖突,內核中大量update/insert會話在等待行鎖釋放,導致CPU使用率達到70%左右,數據庫操作變慢。
查看CES指標行鎖等待個數、MDL鎖數量,下圖僅供參考:



發生死鎖的表:
********* 1. row *********
Table: table_test Create Table: CREATE TABLE table_test(
...
CONSTRAINT act_fk_exe_parent FOREIGN KEY (parent_id_) REFERENCES act_ru_execution (id_) ON DELETE CASCADE,
CONSTRAINT act_fk_exe_procdef FOREIGN KEY (proc_def_id_) REFERENCES act_re_procdef (id_),
CONSTRAINT act_fk_exe_procinst FOREIGN KEY (proc_inst_id_) REFERENCES act_ru_execution (id_) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT act_fk_exe_super FOREIGN KEY (super_exec_) REFERENCES act_ru_execution (id_) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
原因分析
- 部分表發生死鎖,導致CPU一定幅度抬升。
- 死鎖的表中有大量的外鍵,這些表的記錄在更新時,不僅需要獲取本表的行鎖,還需要檢查外鍵關聯表的記錄,獲取相應鎖。高并發情況下,比普通表更容易鎖沖突或死鎖,詳解。
- 當MySQL檢查到死鎖的表時,會進行事務的回滾。其影響范圍不僅是某個表,還會影響外鍵所在的表,最終導致數據庫相關操作變慢。
解決方案
建議排查并優化死鎖表相關的業務,業務上合理使用外鍵,避免更新沖突,避免產生死鎖。
TaurusDB實例CPU升高定位思路
TaurusDB實例CPU升高或100%,引起業務響應慢,新建連接超時等。
場景1 慢查詢導致CPU升高
問題原因:大量慢SQL導致實例CPU升高,需要優化相應的慢SQL。
排查思路:
查看CPU使用率和慢日志個數統計監控指標。


- 如果慢日志個數很多,且與CPU曲線吻合,可以確定是慢SQL導致CPU升高。
- 如果慢日志個數不多,但與CPU使用率基本一致,進一步查看行讀取速率指標是否與CPU曲線吻合。


如果吻合,說明是少量慢SQL訪問大量行數據導致CPU升高:由于這些慢SQL查詢執行效率低,為獲得預期的結果需要訪問大量的數據導致平均IO高,因此在QPS并不高的情況下(例如網站訪問量不大),也會導致實例的CPU使用率偏高。
解決方案:
- 根據CPU使用率過高的時間點,查看對應時間段的慢日志信息。
- 重點關注掃描行數、返回結果行數超過百萬級別的慢查詢,以及鎖等待時間長的慢查詢。
- 慢查詢用戶可自行分析,或使用數據管理服務(DAS)對慢查詢語句進行診斷。
- 通過分析數據庫執行中的會話來定位執行效率低的SQL。
- 連接數據庫。
- 執行 show full processlist; 。
- 分析執行時間長、運行狀態為Sending data、Copying to tmp table、Copying to tmp table on disk、Sorting result、Using filesort的會話,均可能存在性能問題,通過會話來分析其正在執行的SQL。
場景2 連接和QPS升高導致CPU上升
問題原因:業務請求增高導致實例CPU升高,需要從業務側分析請求變化的原因。
排查思路:
查看QPS、當前活躍連接數、數據庫總連接數、CPU使用率監控指標是否吻合。
QPS的含義是每秒查詢數,QPS和當前活躍連接數同時上升,且QPS和CPU使用率曲線變化吻合,可以確定是業務請求增高導致CPU上升,如下圖:




該場景下,SQL語句一般比較簡單,執行效率也高,數據庫側優化余地小,需要從業務源頭優化。
解決方案:
- 單純的QPS高導致CPU使用率過高,往往出現在實例規格較小的情況下,建議升級實例CPU規格。
- 優化慢查詢,優化方法參照場景1 慢查詢導致CPU升高的解決方案。若優化慢查詢后效果不明顯,建議升級實例CPU規格。
- 對于數據量大的表,建議通過分庫分表減小單次查詢訪問的數據量。
大并發慢查詢導致CPU資源耗盡問題
場景描述
數據庫實例上存在大量并發的select count(0)慢操作,系統CPU耗盡,隨時有宕機的風險。
Show processlist信息:


該sql慢日志查詢信息:


原因分析
應用端大并發觸發select count(0)慢操作,導致系統CPU資源耗盡。
解決方案
步驟 1 申請kill權限,間歇性批量執行kill select count(0)慢操作,定位select count(0)觸發來源,停止來源,并拆分優化sql。
批量kill動作:


步驟 2 CPU idle恢復:

