共計 2500 個字符,預計需要花費 7 分鐘才能閱讀完成。
本篇內容主要講解“MySQL 主從復制延遲原因是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“MySQL 主從復制延遲原因是什么”吧!
在異步或半同步的復制結構中,從庫出現延遲是一件十分正常的事。
雖出現延遲正常,但是否需要關注,則一般是由業務來評估。
如:從庫上有需要較高一致性的讀業務,并且要求延遲小于某個值,那么則需要關注。
首先,簡單概述一下復制邏輯:
1、主庫將對數據庫實例的變更記錄到 binlog 中。
2、主庫會有 binlog dump 線程實時監測 binlog 的變更并將這些新的 events 推給從庫(Master has sent all binlog to slave; waiting for more updates)
3、從庫的 IO Thread 接收這些 events,并將其記錄入 relaylog。
4、從庫的 SQL Thread 讀取 relaylog 的 events,并將這些 events 應用(或稱為重放)到從庫實例。
上述為默認的異步復制邏輯,半同步復制又有些許不同,此處不再贅述。
此外,判斷從庫有延遲是十分簡單的一件事:
在從庫上通過 SHOW SLAVE STATUS
檢查 Seconds_Behind_Master 值即可。
產生延遲的原因及處理思路
〇 主庫 DML 請求頻繁(tps 較大)
即主庫寫請求較多,有大量 insert、delete、update 并發操作,短時間產生了大量的 binlog。
【原因分析】
主庫并發寫入數據,而從庫 SQL Thread 為單線程應用日志,很容易造成 relaylog 堆積,產生延遲。
【解決思路】
做 sharding,通過 scale out 打散寫請求。或考慮升級到 MySQL 5.7+,開啟基于邏輯時鐘的并行復制。
〇 主庫執行大事務
比如大量導入數據,INSERT INTO $tb1 SELECT * FROM $tb2、LOAD DATA INFILE 等
比如 UPDATE、DELETE 了全表等
Exec_Master_Log_Pos 一直未變,Slave_SQL_Running_State 為 Reading event from the relay log
分析主庫 binlog,看主庫當前執行的事務也可知曉。
【原因分析】
假如主庫花費 200s 更新了一張大表,在主從庫配置相近的情況下,從庫也需要花幾乎同樣的時間更新這張大表,此時從庫延遲開始堆積,后續的 events 無法更新。
【解決思路】
拆分大事務,及時提交。
〇 主庫對大表執行 DDL 語句
現象和主庫執行大事務相近。
檢查 Exec_Master_Log_Pos 一直未動,也有可能是在執行 DDL。
分析主庫 binlog,看主庫當前執行的事務也可知曉。
【原因分析】
1、DDL 未開始,被阻塞,SHOW SLAVE STATUS 檢查到 Slave_SQL_Running_State 為 waiting for table metadata lock,且 Exec_Master_Log_Pos 不變。
2、DDL 正在執行,SQL Thread 單線程應用導致延遲增加。Slave_SQL_Running_State 為 altering table,Exec_Master_Log_Pos 不變
【解決思路】
通過 processlist 或 information_schema.innodb_trx 來找到阻塞 DDL 語句的查詢,干掉該查詢,讓 DDL 正常在從庫執行。
DDL 本身造成的延遲難以避免,建議考慮:
① 業務低峰期執行
② set sql_log_bin= 0 后,分別在主從庫上手動執行 DDL(此操作對于某些 DDL 操作會造成數據不一致,請務必嚴格測試)
〇 主庫與從庫配置不一致:
【原因分析】
硬件上:主庫實例服務器使用 SSD,而從庫實例服務器使用普通 SAS 盤、cpu 主頻不一致等
配置上:如 RAID 卡寫策略不一致,OS 內核參數設置不一致,MySQL 落盤策略不一致等
【解決思路】
盡量統一 DB 機器的配置(包括硬件及選項參數)
甚至對于某些 OLAP 業務,從庫實例硬件配置高于主庫等
〇 表缺乏主鍵或唯一索引
binlog_format=row 的情況下,如果表缺乏主鍵或唯一索引,在 UPDATE、DELETE 的時候可能會造成從庫延遲驟增。
此時 Slave_SQL_Running_State 為 Reading event from the relay log。
并且 SHOW OPEN TABLES WHERE in_use= 1 的表一直存在。
Exec_Master_Log_Pos 不變。
mysqld 進程的 cpu 幾近 100%(無讀業務時),io 壓力不大
【原因分析】
做個極端情況下的假設,主庫更新一張 500w 表中的 20w 行數據,該 update 語句需要全表掃描
而 row 格式下,記錄到 binlog 的為 20w 次 update 操作,此時 SQL Thread 重放將特別慢,每一次 update 可能需要進行一次全表掃描
【解決思路】
檢查表結構,保證每個表都有顯式自增主鍵,并建立合適索引。
〇 從庫自身壓力過大
【原因分析】
從庫執行大量 select 請求,或業務大部分 select 請求被路由到從庫實例上,甚至大量 OLAP 業務,或者從庫正在備份等。
此時可能造成 cpu 負載過高,io 利用率過高等,導致 SQL Thread 應用過慢。
【解決思路】
建立更多從庫,打散讀請求,降低現有從庫實例的壓力。
〇 MyISAM 存儲引擎
此時從庫 Slave_SQL_Running_State 為 Waiting for table level lock
【原因分析】
MyISAM 只支持表級鎖,并且讀寫不可并發操作。
主庫在設置 @@concurrent_insert 對應值的情況下,能并發在 select 時執行 insert,但從庫 SQL Thread 重放時并不可并發,有興趣可以再去看看 myisam 這塊的實現。
【解決思路】
當然是選擇原諒它了,既然選擇了 MyISAM,那么也應該要有心理準備。(還存在其他場景,也不推薦 MyISAM 在復制結構中使用)
改成 InnoDB 吧。
到此,相信大家對“MySQL 主從復制延遲原因是什么”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!