本文介紹常見的RDS MySQL唯讀執行個體延遲時間變長的原因及解決方案。
問題描述
由於阿里雲雲資料庫RDS唯讀執行個體採用MySQL原生的基於日誌複製技術(非同步複製或半非同步複製),必然會有同步延遲。延遲會導致唯讀執行個體與主執行個體的資料出現不一致,從而導致業務出現問題。另外,延遲也有可能引起日誌堆積,導致唯讀執行個體空間被迅速消耗。
若主執行個體正產生大量的日誌,有可能會使唯讀執行個體被鎖定。
日誌複寫延遲是通過
show slave status \G
命令的second_behind_master(單位為秒)欄位顯示的。延遲的計算方法:延遲時間長度=目前時間(執行
show slave status \G
命令的時間)-當前備庫上正在應用的事務在主庫提交的時間。
按照延遲時間長度可將延遲分為以下兩種類型:
小於或等於1秒的延遲:由系統延遲計算精度、計算方法、採樣時刻、監控時間粒紋引起,無問題,無需關注。
大於1秒的延遲:由唯讀執行個體規格過小、主執行個體的TPS過高、主執行個體的大事務、主執行個體的DDL語句執行時間較長引起,需要排查處理。
問題原因
小於或等於1秒的延遲
小於1秒延遲出現原因:由監控時間範圍設定過長引起,實際並不存在小於1秒的延遲,無需關注。
如果設定的監控時間範圍比較長,就會導致監控的時間粒紋比較大。例如,如果監控的時間範圍為3小時,預設的監控的時間粒紋就會達到30秒級,每個時刻計算得出的資料就是30秒的平均值,就會出現小於1秒的延遲。而實際每個時刻計算出的延遲最小粒度為1秒。
如果想看到更準確的延遲,可以到RDS控制台的效能趨勢頁面,將監控時間範圍縮小到6分鐘以內,可以看到時間粒紋為1秒的監控值。詳情請參見效能趨勢。
1秒延遲出現原因:由系統延遲計算精度、計算方法、採樣時刻、是否存在跨秒事務引起,實際並不存在1秒的延遲,無需關注。
RDS MySQL中延遲的計算精度是秒級的,會忽略“秒”這一位之後的資料。例如,00:00:00.95會按照00:00:00來計算,00:00:01.05會按照00:00:01來計算。如果採集時刻在整秒剛過(例如00:00:01.05),就可能會導致將不滿1秒的延遲(例如0.15秒)計算為1秒,如下表中第4行所示:
事務
主庫提交時間
備庫提交時間
目前時間(show slave status命令執行的時間)
秒級精度的延遲
Trx1
00:00:00.30
00:00:00.50
00:00:00.35
0(0.35)-0(0.3)=0秒
00:00:00.45
0(0.45)-0(0.3)=0秒
Trx2
00:00:00.90
00:00:01.10
00:00:00.95
0(0.95)-0(0.9)=0秒
00:00:01.05
1(1.05)-0(0.9)=1秒
由於採集的間隔是1整秒,所以每次採集時刻都在整秒剛過,如果有業務壓力、存在跨秒事務,這樣每次都可能採集到1秒的延遲。而如果採集的時刻不是在整秒剛過(例如00:00:00.95),就會將延遲計算為0秒,如上表中第3行所示。
大於1秒的延遲
大於1秒的延遲,由以下幾種可能的原因引起:
唯讀執行個體規格過小
這類延遲情境經常出現在唯讀執行個體規格和主執行個體規格相差較大,而且唯讀執行個體負載較重的情況下。例如,唯讀執行個體IOPS過高。唯讀執行個體為了和主執行個體保持同步,採用了MySQL原生的日誌複製技術,由一個IO線程和一個SQL線程來完成。IO線程負責將主執行個體的日誌拉取到唯讀執行個體,SQL線程負責將這些日誌應用到唯讀執行個體。這兩個線程會消耗唯讀執行個體的IO資源,所以當唯讀執行個體的IOPS配置不高時,會導致唯讀執行個體資料延遲。可以登入RDS控制台,通過監控資訊確認IOPS較高。
主執行個體的TPS(Transaction Per Second)過高
由於唯讀執行個體與主執行個體之前的同步採用的是單線程同步,若主執行個體並發多線程寫入資料,在主執行個體TPS過高的情況下容易出現唯讀執行個體的資料延遲,可以通過觀察唯讀執行個體的TPS與主執行個體的TPS效能資料來判斷。
大事務寫入
主執行個體執行一個涉及資料量非常大的update、delete、insert…select、replace…select等事務操作時,會產生大量的日誌資料並同步到唯讀執行個體。唯讀執行個體需要花費與主執行個體相同的時間來完成該事務,因此會導致唯讀執行個體同步延遲。例如,在主執行個體上執行一個持續80秒的刪除操作,唯讀執行個體進行相同操作時也需要花費很長時間,於是會出現延遲情況。
雖然目前支援多表並發事務,但對於單表事務,只能單線程來完成複製,因此也會比較慢。
主執行個體的DDL語句執行時間較長
唯讀執行個體和主執行個體資料同步是串列進行的,如果DDL操作在主執行個體操作的表過大,執行時間很長,或者執行大量慢查詢,則會產生大量的暫存資料表,將導致磁碟容量不足和磁碟IO增加,從而導致同步延遲。常見操作例如create index、repair table、alter table add column等。
唯讀執行個體上執行的查詢或未完成的事務阻塞了來自主執行個體的DDL執行。
特殊情況
複製的SQL語句,沒有走到合適的索引,而導致大量的全表掃描,邏輯讀暴漲。
如果某張表中只有唯一索引,沒有主鍵,且唯一索引為空白,slave複製時,會優先執行UK的執行計畫,而不是讓最佳化器選擇。所以即使where條件是個不錯的過濾項,也一定是執行UK的執行計畫。
排查方法
當唯讀執行個體出現延遲時,小於或等於1秒的延遲無問題,無需處理。可以根據排查方法定位大於1秒延遲的原因:
唯讀執行個體規格過小
在RDS控制台【雲資料庫RDS/執行個體列表「唯讀執行個體」/基本資料/配置資訊/執行個體規格】中查看執行個體規格,具體規格資訊參見RDS MySQL標準版(原X86)唯讀執行個體規格列表、RDS MySQL倚天版(原ARM)唯讀執行個體規格列表。
在RDS控制台【雲資料庫RDS/執行個體列表「唯讀執行個體」/監控與警示】中查看監控資訊,檢查唯讀執行個體的CPU/記憶體/IO頻寬/串連數,確認唯讀執行個體是否存在資源瓶頸。
主執行個體的TPS(Transaction Per Second)過高
確認主執行個體/唯讀執行個體的TPS是否正常,TPS相關資料可以通過自治服務的效能趨勢頁面查看,詳情請參見效能趨勢。
大事務寫入
在大事務同步到唯讀執行個體導致延遲出現時,登入資料庫,執行
show slave status \G
SQL語句,確認 Seconds_Behind_Master 不斷變化,而 Exec_Master_Log_Pos 卻保持不變,說明唯讀執行個體的SQL線程在執行一個大事務或者DDL操作,系統顯示類似如下結果:最後通過
show processlist;
語句定位具體的線程。唯讀執行個體執行
show slave status \G
命令,確定是否存在中繼資料鎖。如果binlog是row模式,大事務會導致binlog檔案比較大。可以通過命令
show binary logs;
查看File_size的數值,如果大於max_binlog_size參數的大小,則一定是產生了大事務。
主執行個體的DDL語句執行時間較長
binlog來不及切割而變得很大,檢查唯讀執行個體的binlog增長量,從側面判斷是否存在DDL寫入。
檢查唯讀執行個體是否存在無主鍵表的刪除或者更新操作,可以通過在唯讀執行個體上執行
show engine innodb status \G
語句查看,或者執行show open tables;
語句後,查看輸出結果的in_use列的值為1的表。查看慢日誌資訊,確認是否存在optimize、alter、repair和create等DDL操作,詳情請參見慢日誌分析。
特殊情況【Unique Key為NULL的情況】
通過 sys.schema_index_statistics 視圖,定位業務表是否無主鍵只有唯一索引的欄位。
進一步確認符合條件欄位是否為NULL。
解決方案
如果對執行個體或資料有修改、變更等風險操作,務必注意執行個體的容災、容錯能力,確保資料安全。
如果對執行個體(包括但不限於ECS、RDS)等進行配置與資料修改,建議提前建立快照或開啟RDS記錄備份等功能。
如果在阿里雲平台授權或者提交過登入帳號、密碼等安全資訊,建議及時修改。
根據上述排查方法定位的原因選擇對應的解決方案:
唯讀執行個體規格過小
建議升級唯讀執行個體規格,使唯讀執行個體的配置大於或者等於主執行個體的配置,避免由於唯讀執行個體規格較小導致延遲,詳情請參見變更配置。
主執行個體的TPS(Transaction Per Second)過高
如果TPS過高,則需要對業務進行最佳化或者拆分,保證主執行個體的TPS不會導致唯讀執行個體出現延遲。
大事務寫入
建議將大事務拆分為小事務分別執行。例如,在delete語句中增加where條件子句,限制每次刪除的資料量,將一次刪除操作拆分為多次資料量較小的刪除操作進行。這樣唯讀執行個體可以迅速地完成事務的執行,不會造成資料的延遲。
主執行個體的DDL語句執行時間較長
對於DDL直接引起的唯讀執行個體延遲,建議在業務低峰期執行這些DDL。可根據業務情況通過以下方法進行解決:
業務保障角度:優先開啟自動擴容,或者設定磁碟警示閾值為90%,及時擴容磁碟,詳情請參見如何擴容RDS執行個體。
SQL最佳化的角度:開啟SQL洞察,定期進行業務SQL語句效能排查,詳情請參見SQL洞察和審計。
負載角度:通過設定磁碟警示,手動升配進行解決。
對於來自主執行個體的DDL語句在唯讀執行個體上被阻塞的情況:
在唯讀執行個體上執行
show processlist;
語句,確認SQL線程的狀態為“waiting for table metadata lock”。使用kill命令終止唯讀執行個體上引起阻塞的會話,恢複唯讀執行個體和主執行個體的資料同步,詳情請參見解決MDL鎖導致無法操作資料庫的問題。
特殊情況
可直接對無主鍵業務表添加顯式主鍵即可。
常見問題
Q:為什麼我的執行個體中,部分唯讀執行個體有1秒延遲的現象?
A:每個執行個體的採集程式、啟動時間都不一樣,有些執行個體的採集時刻恰巧在剛過整秒的時間點,就會有此現象。其他執行個體的採集時刻不在剛過整秒的時間點,就不會有這個現象。詳情請參見小於或等於1秒的延遲。
Q:1秒延遲對我的執行個體有沒有影響?
A:沒有影響。1秒延遲並不代表實際存在1秒的延遲。例如,當實際延遲只有0.1秒時,如果採集時間在剛過整秒的時刻,也會採集到1秒的延遲,它是由系統延遲計算精度、計算方法、採樣時刻引起的。詳情請參見小於或等於1秒的延遲。
建議在配置警示或者代理的讀庫延遲閾值時,要根據自己的實際需求與配置,並滿足:讀庫延遲閾值>1秒。
Q:唯讀執行個體頁面中顯示複製中斷,或收到了 Slave_SQL_Running 或 Slave_IO_Running 的警示,應該如何處理?
A:可以排查以下三個問題:
檢查唯讀執行個體儲存空間是否充足。
當儲存空間不足時,唯讀執行個體無法接收到主執行個體的Binlog。
說明可以在唯讀執行個體基本資料頁面的使用量統計地區,查看儲存空間使用方式。
檢查複寫延遲。
如果複寫延遲在5分鐘內連續大於5秒,表示唯讀執行個體延遲過高,會產生複寫延遲的警示。導致複寫延遲的原因可能是主庫寫入過於頻繁與執行個體效能不匹配、長期存在大事務等。
說明可以在唯讀執行個體基本資料頁面左側單擊監控與報警,在標準監控頁簽,查看節點複寫延遲(second)。
檢查慢日誌。
慢日誌非常消耗執行個體效能,可能會增加複寫延遲,對複製產生較大影響。
說明可以在唯讀執行個體基本資料頁面,通過以下兩種方式查看慢日誌詳情:
在左側單擊日誌管理,在慢日誌明細頁簽查看。
在左側選擇自治服務(原CloudDBA)>慢SQL,在頁面中查看。
若非上述問題產生的複製中斷,則不需要處理,系統會自動巡檢,修複產生複製中斷的執行個體。