MySQL高可用(二)主備延時如何解決?

大雜草發表於2020-12-22

從上篇文章我們知道主備同步是依賴於 binlog,主庫負責生產 binlog,備庫負責消費 binlog,從而實現主備同步。

今天我們來學習一下主備同步裡的一個重點的問題:主備延時。

主備延時,簡單來說,就是主庫和備庫的資料一致出現一定的時間差,比如備庫的此刻的資料快照是主備5分鐘前的資料快照,那就說明主備延時有5分鐘。

主備延遲是怎麼產生的

產生主備延遲的根本原因是備庫上消費 binlog 的速度趕不上主庫產生 binlog 的速度。比如:

  • 大事務,例如一次性delete很多資料;
  • 大表的DDL;
  • 備庫壓力大。例如有些像運維、訂單等統計分析在備機上跑;
  • 主備庫的伺服器的配置不同,主庫的伺服器配置好,備庫的伺服器配置差。

主備延遲的排查之路

網路

網路可能導致主備延遲的問題,比如主庫或者備庫的頻寬滿負載、主備之間網路延遲很大,有可能會導致主庫的 binlog 沒有全量傳輸到備庫,造成延遲。

機器效能

備庫 使用了爛機器? 比如主庫使用了 SSD,而備庫使用的是 SATA。

備庫 高負載? 可能在備庫上做統計分析,導致備庫的負載很高。可使用 top 命令進行排查。

備庫 磁碟有問題? 磁碟、raid卡、排程策略有問題的情況下,有的時候會出現單個IO延遲很高的情況。可使用 iostat 檢視 IO 執行情況。

大事務

是否經常有大事務? 比如在 RBR 模式下,執行帶有大量的 delete 操作,或者一個表的 alter 操作等,都會導致延時情況的發生。可通過 processlist 命令檢視相關資訊,或者使用 mysqlbinlog 檢視 binlog 中的 SQL 就能快速確認。

鎖衝突問題也可能導致備庫的 SQL 執行緒執行慢。比如一些 select ... for update 的 SQL。可通過 processlist 和 檢視 information_schema 下面與鎖和事務相關的表來檢視分析。

引數

如果使用的是 InnoDB 引擎,可以調整 innodb_flush_log_at_trx_commitsync_binlog 引數來提升複製速度。

sync_binlog 的預設值是 0,MySQL 不會將 binlog 同步到磁碟,其值表示每寫多少 binlog 同步一次磁碟。

innodb_flush_log_at_trx_commit 其值表示每一次事務提交或事務外的指令需要把日誌 flush 到磁碟。

注:這種調整可能會影響資料的安全性,需要結合業務來考慮。

多執行緒

在 MySQL 5.6 版本之前,MySQL採用單執行緒複製,而從 5.6 開始,正式支援多執行緒複製。

如果是單執行緒同步,單個執行緒存在寫入瓶頸,導致主備延遲,那就先調整為多執行緒試試效果。

可以通過 show processlist 檢視是否有多個同步執行緒,也可以檢視引數的方式檢視是否使用多執行緒(show variables like '%備庫_parallel%'

show variables like '%備庫_parallel%'

當你看到是上圖這種結果的時候,恭喜你,你使用的是單執行緒。使用下面那行命令改造成多執行緒複製:

STOP 備庫 SQL_THREAD;SET GLOBAL 備庫_parallel_type='LOGICAL_CLOCK';SET GLOBAL 備庫_parallel_workers=8;START 備庫 SQL_THREAD;

改造後如下圖所示:

show variables like '%備庫_parallel%'

參考資料

相關文章