一、現(xiàn)象
凌晨對(duì)線上一張表添加索引,表數(shù)據(jù)量太大(1億+數(shù)據(jù),數(shù)據(jù)量50G以上),造成主從延遲幾個(gè)小時(shí),各個(gè)依賴從庫(kù)的系統(tǒng)無(wú)法查詢數(shù)據(jù),最終影響業(yè)務(wù)。
現(xiàn)在就梳理下主從延遲的原理。
二、原理
根據(jù) MySQL 官方文檔 MySQL Replication Implementation Details 中的描述,MySQL 主從復(fù)制依賴于三個(gè)線程:master一個(gè)線程(Binlog dump thread),slave兩個(gè)線程(I/O thread和SQL thread)。主從復(fù)制流程如下圖:

master 服務(wù)器和 slave 服務(wù)器連接時(shí),創(chuàng)建Binlog dump thread以發(fā)送bin log數(shù)據(jù):
- 一個(gè)
Binlog dump thread對(duì)應(yīng)一個(gè) slave 服務(wù)器;
Binlog dump thread從bin log獲取數(shù)據(jù)時(shí)會(huì)加鎖,獲取到數(shù)據(jù)后,立即釋放鎖。
當(dāng) slave 服務(wù)器收到 START_SLAVE 命令時(shí),會(huì)創(chuàng)建I/O thread和SQL thread:
I/O thread以拉的方式,從 master 讀取事件,并存儲(chǔ)到 slave 服務(wù)器的relay log中;
SQL thread從relay log中讀取事件并執(zhí)行;
slave可以按照自己的節(jié)奏讀取和更新數(shù)據(jù),也可以隨意操作復(fù)制進(jìn)程(啟動(dòng)和停止)。
注: START_SLAVE命令成功啟動(dòng)線程后,如果后面I/O thread或SQL thread因?yàn)槟承┰蛲V?,則不會(huì)有任何的警告,業(yè)務(wù)方無(wú)法感知。可以通過(guò)查看 slave 的 error 日志,或者通過(guò) SHOW SLAVE STATUS 查看 slave 上的線程狀態(tài)。
通過(guò) SHOW PROCESSLIST 可查看線程狀態(tài):
Binlog dump thread:
mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
Id: 2
User: root
Host: localhost:32931
db: NULL
Command: Binlog Dump
Time: 94
State: Has sent all binlog to slave; waiting for binlog to
be updated
Info: NULL
I/O thread 和 SQL thread:
mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
Id: 10
User: system user
Host:
db: NULL
Command: Connect
Time: 11
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 11
User: system user
Host:
db: NULL
Command: Connect
Time: 11
State: Has read all relay log; waiting for the slave I/O
thread to update it
Info: NULL
三、分析
根據(jù)上面的原理,由于slave是單線程(I/O thread)讀取數(shù)據(jù),單線程(SQL thread)更新數(shù)據(jù),而master是多線程寫入,那么只要master寫入的頻率大于slave讀取更新的頻率,就有可能出現(xiàn)主從延遲的情況,如:
master寫入tps較高,大于slave更新速度;
slave執(zhí)行某些語(yǔ)句耗時(shí)較長(zhǎng),如持有鎖等;
master執(zhí)行某些DDL語(yǔ)句時(shí),執(zhí)行的時(shí)間較長(zhǎng),在slave也執(zhí)行相同的時(shí)間;
此處創(chuàng)建了索引,咨詢 DBA,產(chǎn)生的bin log文件有100多G,數(shù)據(jù)量太大,導(dǎo)致從庫(kù)I/O thread一直讀取DDL操作產(chǎn)生的bin log事件,而影響到正常的業(yè)務(wù)DML事件的更新,從而表現(xiàn)為主從同步延遲。
四、解決方案
從主從延遲的原因來(lái)看,解決方案可以從以下幾個(gè)方向入手:
- 業(yè)務(wù)選型,對(duì)于無(wú)法忍受從庫(kù)延遲的架構(gòu),可選擇分布式架構(gòu)等,避開(kāi)從庫(kù)延遲問(wèn)題
- 執(zhí)行時(shí)間,對(duì)大表進(jìn)行線上
DDL操作盡量選擇凌晨等業(yè)務(wù)量較小的時(shí)候
- 硬件配置,升級(jí)從庫(kù)硬件配置,如SSD
- 減少請(qǐng)求,增加緩存層,減少讀請(qǐng)求落庫(kù)
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接
您可能感興趣的文章:- MySQL主從復(fù)制延遲原因以及解決方案
- MySQL5.6升級(jí)5.7時(shí)出現(xiàn)主從延遲問(wèn)題排查過(guò)程
- MySQL主從同步延遲的原因及解決辦法
- MYSQL主從不同步延遲原理分析及解決方案
- 減少mysql主從數(shù)據(jù)同步延遲問(wèn)題的詳解
- 深入mysql主從復(fù)制延遲問(wèn)題的詳解
- MySQL主從延遲問(wèn)題解決