Mysql的主從同步/復(fù)制的原理分析
為什么要主從同步?
- 數(shù)據(jù)容災(zāi)、備份。當(dāng)我們的數(shù)據(jù)庫只使用一臺服務(wù)時,如果我們的數(shù)據(jù)庫遭到破壞,例如黑客的攻擊、人為操作的失誤等等情況。這時候我們就可以在一定程度上保障我們數(shù)據(jù)庫的恢復(fù)。
- 緩解 MySQL 主服務(wù)的壓力。主服務(wù)器寫數(shù)據(jù),從服務(wù)器讀數(shù)據(jù)(讀寫分離)。
Mysql主從同步架構(gòu)有哪些?
一主一從/多從架構(gòu)
- 適用于讀多寫少
雙主/多主
- 適用于讀寫均勻,同時整體的并發(fā)量也不算低,至少超出了單庫的承載閾值
多主一從
- 適用于寫大于讀
級聯(lián)復(fù)制架構(gòu)
- 存在兩層從庫,這實際上屬于一主多從架構(gòu)的升級版,畢竟如果一個主節(jié)點存在多個從節(jié)點時,多個從節(jié)點都會同時去主節(jié)點拉取新數(shù)據(jù),如果數(shù)據(jù)量較大,就會導(dǎo)致主節(jié)點的I/O負(fù)載過高,因此這種級聯(lián)復(fù)制架構(gòu)要解決的問題,也就是多個從庫會對主庫造成太大壓力的問題。
- 下面會根據(jù)原理介紹為什么級聯(lián)復(fù)制架構(gòu)更好
主從架構(gòu),都會存在致命硬傷,同時也會存在些許問題需要解決:
- 硬傷:木桶效應(yīng),一個主從集群中所有節(jié)點的容量,受限于存儲容量最低的哪臺服務(wù)器。
- 數(shù)據(jù)一致性問題:由于同步復(fù)制數(shù)據(jù)的過程是基于網(wǎng)絡(luò)傳輸完成的,所以存儲延遲性。
- 腦裂問題:從節(jié)點會通過心跳機(jī)制,發(fā)送網(wǎng)絡(luò)包來判斷主機(jī)是否存活,網(wǎng)絡(luò)故障情況下會產(chǎn)生多主。
Mysql主從復(fù)制的原理/整體流程

- master 服務(wù)器會將 SQL 記錄通過多 dump 線程寫入到 binary log 中。
- 主庫會為每個從庫創(chuàng)建一個專屬的 dump 線程。
- slave 服務(wù)器開啟一個 io thread 線程向服務(wù)器發(fā)送請求,向 master 服務(wù)器請求 binary log。master 服務(wù)器在接收到請求之后,根據(jù)偏移量將新的 binary log 發(fā)送給 slave 服務(wù)器。
- slave 服務(wù)器收到新的 binary log 之后,寫入到自身的 relay log 中,這就是所謂的中繼日志。
- slave 服務(wù)器,單獨開啟一個 sql thread 讀取 relay log 之后,寫入到自身數(shù)據(jù)中。
級聯(lián)復(fù)制架構(gòu)為什么好?
級聯(lián)復(fù)制架構(gòu)好的原因大家可以從這個圖中可以看出,主庫會為每個從庫建立一個Dump線程,而Dump線程又擔(dān)負(fù)著重要的作用:將監(jiān)聽到的數(shù)據(jù)通過網(wǎng)絡(luò)傳輸發(fā)送給從庫??上攵绻麖膸爝^多對給主庫帶來巨大的IO壓力,那如果只給一個從庫發(fā)送數(shù)據(jù),并且這個從庫又擔(dān)任其他從庫的復(fù)制職責(zé),這樣就會減輕我們主庫的壓力,從而提高我們主庫的性能。

Mysql主從復(fù)制注意點
從庫 I/O 線程主要職責(zé)是“接收 + 寫 relay log”
- 連接到主庫并請求binlog內(nèi)容
- 接收主庫dump線程發(fā)送的binlog事件
- 將接收到的binlog事件寫入從庫的relay log(中繼日志)
- 更新從庫的master info信息(記錄已讀取的主庫binlog位置)
- 斷點續(xù)傳:如果連接中斷,IO線程會按照配置的重試策略定期嘗試重新連接
主庫 dump 線程負(fù)責(zé)從 binlog 中讀取變更數(shù)據(jù),并“源源不斷推送”給從庫。
- 等待從庫連接并發(fā)送binlog位置請求
- 根據(jù)從庫請求的binlog文件名和位置(或GTID)定位讀取點
- 以事件(event)為單位讀取binlog內(nèi)容
- 將事件發(fā)送給從庫的I/O線程
- 在沒有新事件時進(jìn)入等待狀態(tài)(不是持續(xù)推送)
- 即使主庫沒有數(shù)據(jù)變化,主庫 dump 線程 也會根據(jù) master_heartbeat_period 發(fā)送一個 Heartbeat log event 給 從庫 IO 線程,作為 binlog 的一部分傳輸,用來維持連接活躍、防止超時斷線。
- 主庫是怎么判斷從庫有沒有數(shù)據(jù)?
- 主庫不判斷!是從庫告訴主庫它需要從哪個位置開始同步!
MySQL 支持三種 binlog 格式(也就是傳輸給從庫的數(shù)據(jù)格式)
STATEMENT (不推薦,有風(fēng)險)
- 最早期的方式,記錄執(zhí)行的原始 SQL 語句
- 優(yōu)點:可讀(看得懂)、日志體積小、性能開銷小
- 缺點:有副作用可能不一致(如 UUID、now())
ROW(依舊是邏輯日志)
- 不記錄 SQL,而是記錄每一行數(shù)據(jù)的變更
對比redolog
- redolog:表空間X,頁號Y,偏移量Z處的數(shù)據(jù)從0x1234改為0x5678
- redolog記錄的是具體的物理存儲位置而ROW僅存儲表信息以及數(shù)據(jù)因此依舊是邏輯日志(這里大家不要混淆以為記錄數(shù)據(jù)就是物理日志)
- 記錄信息:表的 database name + table name、表的 列結(jié)構(gòu)、對應(yīng)數(shù)據(jù)行的變化
- 優(yōu)點:準(zhǔn)確,幾乎無副作用問題
- 缺點:日志體積大、不可讀(二進(jìn)制)、性能開銷大(行變更多則更慢)
MIXED
- 自動在 STATEMENT 和 ROW 之間切換,MySQL 自行判斷
主從復(fù)制數(shù)據(jù)的模式(重點)
相信大家看有的博客說Mysql主從模式三種或有四種模式的,錯大錯特錯,其實就兩種模式,其他兩種是基于第二個模式配置出來的,下面給大家具體介紹一下:

異步復(fù)制(默認(rèn))
- 客戶端發(fā)送請求先寫入主庫并返回客戶端,然后再異步同步給從庫
- 優(yōu)點:返回給客戶端快,不會因為同步從庫帶來阻塞
- 缺點:主從數(shù)據(jù)不一致的風(fēng)險
半同步模式(推薦)
- 在異步同步的基礎(chǔ)上等待從庫返回結(jié)果再返回給客戶端
- 優(yōu)點:極大的保證了主庫和從庫的數(shù)據(jù)一致性
- 缺點:對客戶端的阻塞帶來影響
內(nèi)部細(xì)節(jié)
- 如果從庫相應(yīng)時間過長默認(rèn)10秒,會切換為異步同步模式
同時為了避免網(wǎng)絡(luò)延遲造成主庫長時間收不到從庫的ACK,因此在配置半同步式復(fù)制時,會有一個rpl_semi_sync_master_timeout參數(shù)來控制超時時間,其默認(rèn)值是10000ms/10s,如若主庫在10s內(nèi)依舊未收到從庫的ACK,則會將復(fù)制模式切換成異步模式,切成異步模式后,會在后續(xù)網(wǎng)絡(luò)正常后再次切回半同步模式。
- 對于多個從庫節(jié)點可以配置有多少個從庫返回就給客戶端響應(yīng)
5.7版本后對主從一致性保障策略
AFTER_SYNC(默認(rèn),增強(qiáng)半同步復(fù)制)【其他博客的第三種模式】
當(dāng)主庫未收到從庫的ACK之前,也不會在主庫上提交事務(wù),也就是保證了主從節(jié)點的數(shù)據(jù)強(qiáng)一致性,解決了after-commit中存在的問題。
AFTER_COMMIT(傳統(tǒng)半同步復(fù)制,可能出現(xiàn)數(shù)據(jù)不一致)
- 主庫在未收到從庫的ACK之前,雖然不會給客戶端返回寫入成功,但本質(zhì)上在MySQL中會提交事務(wù),也就是主庫中的其他事務(wù)是可以看見對應(yīng)數(shù)據(jù)的,當(dāng)此時出現(xiàn)宕機(jī)時,就會導(dǎo)致舊主上能查詢出的數(shù)據(jù),在新主(原本的從庫)上無法查詢出來了。
- 兩者之間的區(qū)別就在于:對主從節(jié)點的數(shù)據(jù)嚴(yán)格性不同,一般情況下,無損復(fù)制會比傳統(tǒng)半同步復(fù)制開銷更大一些,因為事務(wù)遲遲不提交,會導(dǎo)致對應(yīng)的鎖資源不會主動釋放,其他需要獲取對應(yīng)鎖資源的事務(wù)只能阻塞等待,這會造成主庫的整體性能出現(xiàn)一定影響。
同步復(fù)制(本身不支持,需通過半同步復(fù)制設(shè)置為等待所有從庫)【其他博客中第四種模式】
- 對于同步復(fù)制而言,Master主機(jī)將事件發(fā)送給Slave主機(jī)后會觸發(fā)一個等待,直到所有Slave節(jié)點(如果有多個Slave)返回數(shù)據(jù)復(fù)制成功的信息給Master。這種復(fù)制方式最安
- 全,但是同時,效率也是最差的。
Mysql對于從庫的一些優(yōu)化/策略
- 從庫的執(zhí)行策略
延遲復(fù)制
延遲復(fù)制通常用于一些特殊場景,它可以支持從庫數(shù)據(jù)的延遲同步,也就是當(dāng)從庫上的I/O線程,將主庫的Bin-log日志請求回來后,從節(jié)點的SQL線程并不會立刻解析日志執(zhí)行,而是等待一段時間后再解析日志執(zhí)行,這個等待的時間可以由開發(fā)者來配置,一般建議設(shè)為3~6小時之間。
那延遲復(fù)制的好處在于什么呢?
可以防止誤刪操作,如若在主庫上不小心誤刪了大量數(shù)據(jù)、表、庫或其他數(shù)據(jù)庫對象,因為從庫并不是立即執(zhí)行同步過去的記錄,因此可以及時通過從節(jié)點上的數(shù)據(jù)回滾數(shù)據(jù)。除此之外,也能對一些線上Bug進(jìn)行實時觀測,比如一個無法復(fù)現(xiàn)的故障問題發(fā)生時,如果發(fā)現(xiàn)時還在配置的延遲復(fù)制時間內(nèi),則可以去到從庫上觀察。
- 從庫的優(yōu)化手段并行復(fù)制(mysql8.0更完善)
GTID復(fù)制(為什么要先說GTID,因為并行復(fù)制是基于組復(fù)制,而組復(fù)制是基于GTID)
- 在傳統(tǒng)的主從架構(gòu)中,當(dāng)需要發(fā)生主從切換時,需要開發(fā)/運(yùn)維人員手動找到Bin-log的POS同步點,然后執(zhí)行change master to [new-master-pos]命令,將其他從節(jié)點指向新主庫,但每個從節(jié)點可能同步數(shù)據(jù)的進(jìn)度都不一致,因此每個從節(jié)點都需要去找到它上次的POS點,然后指向新主庫,這個工作是不是聽起來就比較繁雜?答案是Yes,不過到了MySQL5.6版本后,開啟了GTID復(fù)制后,則無需手動尋找POS點!
- GTID(Global Transaction ID)也就是全局事務(wù)標(biāo)識符的意思,它由節(jié)點UUID+事務(wù)ID兩部分組成,MySQL在第一次啟動時都會利用UUID隨機(jī)生成一個server_id,還記得在之前的《MVCC機(jī)制》中聊過的事務(wù)ID嘛?MySQL會對每一個寫事務(wù)都分配一個順序遞增的值作為事務(wù)ID,而GTID則是由這兩玩意兒組成的,格式為server_uuid:trx_id。
- 當(dāng)主庫的事務(wù)有了這個全局事務(wù)標(biāo)識后,再發(fā)生主從切換時就無需手動尋點了,僅需要執(zhí)行change master to master_auto_position = 1這條命令即可,它會自動去新主庫上尋找數(shù)據(jù)的同步點,也就是MySQL自身就具備斷點復(fù)制的功能。
為什么需要用GTID代替POS同步點呢?
因為同一個主從集群中,所有節(jié)點加入集群的時間可能會不同
假設(shè)這個集群中每個節(jié)點加入的時間都不一致
- master:日志文件中的同步點POS=1200。
- slave1:日志文件中的同步點POS=1100。
- slave2:日志文件中的同步點POS=800。
- slave3:日志文件中的同步點POS=200。
此時假設(shè)master節(jié)點宕機(jī)或故障了,slave1成為了新主,那么slave2、slave3也應(yīng)該成為新主slave1的從節(jié)點,但此刻問題就來了:原本slave2、slave3的POS同步點是基于master中的日志而言的,但現(xiàn)在主節(jié)點變成了slave1,這時slave2、slave3如何去尋找自己在slave1中的POS點呢?顯然MySQL無法自己完成該工作,因此需要人工指定同步點才行。
而GTID出現(xiàn)的原因,就是為了解決上述這個問題,但具體怎么解決的呢?
GTID的工作過程
master在更新數(shù)據(jù)時,會為每一個寫事務(wù)分配一個全局的GTID,并記錄到Bin-log中。
slave節(jié)點的I/O線程拉取數(shù)據(jù)時,會將讀到的記錄寫到relay-log中,并設(shè)置gtid_next值。
slave節(jié)點的SQL線程執(zhí)行前,會讀取gtid_next值得知接下來該解析哪條日志并執(zhí)行。
slave節(jié)點的SQL線程在執(zhí)行時,會先比對自身的Bin-log日志中是否有對應(yīng)的GTID:
- 有:意味著該GTID對應(yīng)的事務(wù)已經(jīng)執(zhí)行過了,slave會自動忽略掉這條記錄。
- 沒有:SQL解析該GTID對應(yīng)的relay-log記錄并執(zhí)行,再將GTID記錄到Bin-log。
GTID自動尋找同步點的原理
- 開啟GTID后,從庫會基于它來復(fù)制主庫的數(shù)據(jù),此時發(fā)生了主從切換,假設(shè)這時主從集群中有多個從節(jié)點,MySQL首先會選擇距離master的GTID最近的從節(jié)點作為新主,然后將其他從節(jié)點轉(zhuǎn)變?yōu)樾轮鞯膹膸欤渌麖膸鞎鶕?jù)自身gtid_next值,去新主的日志文件中做對比,然后找到各自的同步點,繼續(xù)從新主中復(fù)制數(shù)據(jù)。
- 因為MySQL挑選的是和舊主GTID值,最接近的從節(jié)點作為新主,也就意味著作為新主的從節(jié)點,絕對會比其他從節(jié)點的數(shù)據(jù)要完善,因此新主中的GTID值也是最大的!同時,每個從節(jié)點中都存在一個gtid_next值,記錄著自身下一次要同步數(shù)據(jù)的GTID值,此時剩下的從節(jié)點就可以根據(jù)該值,直接去新主中尋找到自己的同步點位置,從而避免了之前那種手動介入的尷尬場景出現(xiàn)。
- 不過由于GTID復(fù)制是基于事務(wù)來實現(xiàn)的,這也就代表不支持事務(wù)的存儲引擎無法使用這種機(jī)制,在之前的章節(jié)中也聊過,MySQL眾多存儲引擎中,基本上只有InnoDB支持事務(wù),所以GTID機(jī)制基本上只對InnoDB引擎生效。
- 組復(fù)制
GTID復(fù)制則是組復(fù)制的實現(xiàn)基礎(chǔ),而組復(fù)制則是并行復(fù)制的基礎(chǔ),那么什么叫做組復(fù)制呢?組復(fù)制是指將一組并行執(zhí)行的事務(wù),全部放入到一個GTID中記錄,后續(xù)從節(jié)點同步數(shù)據(jù)時,會一次性讀取這一組事務(wù)解析并執(zhí)行,與傳統(tǒng)的GTID區(qū)別如下:
- 傳統(tǒng)的GTID值由節(jié)點ID+事務(wù)ID組成:12EEA4RD6-45AC-667B-33DD-CCC55EF718D:88。
- 組復(fù)制的GTID通過逗號分隔:12EEA4RD6-45AC-667B-33DD-CCC55EF718D:89, 12EEA4RD6-45AC-667B-33DD-CCC55EF718D:89-94, ......。
MySQL如何實現(xiàn)事務(wù)分組的呢?
- MySQL提交事務(wù)時內(nèi)部會調(diào)用ordered_commit函數(shù)來處理相關(guān)工作,其函數(shù)執(zhí)行的邏輯流程圖如下:

當(dāng)一個事務(wù)提交時都會調(diào)用ordered_commit函數(shù),首先會將事務(wù)加入等待事務(wù)組,接著會經(jīng)過三個核心步驟:FLUSH、SYNC、COMMIT,對應(yīng)的也會有三個隊列,它們?nèi)叩墓ぷ髟矶即笾孪嗤?/p>
- ①如果某個事務(wù)進(jìn)入FLUSH隊列時,該隊列還是空的,則這個事務(wù)會擔(dān)任“隊長”的角色。
- ②當(dāng)后續(xù)其他事務(wù)進(jìn)入隊列時,發(fā)現(xiàn)隊列不為空,則會將提交工作委托給隊長來完成。
- ③如上圖中的「事務(wù)1」則是隊長,后續(xù)的都是隊員,但隊長不會無限制等待隊員到來:
從隊長加入的時間點開始,當(dāng)超出binlog_group_commit_sync_delay規(guī)定的時間后,就會進(jìn)行一次組提交。
- 同一時刻只允許一組事務(wù)做這些工作,也就是當(dāng)有另外一組事務(wù)提交時,需要等待上一組事務(wù)提交完成。
- 在做組提交工作時,會將當(dāng)前事務(wù)組的內(nèi)容記錄到Bin-log日志中,同時會將這組事務(wù)記錄成一個GTID,不同事務(wù)之間通過,逗號分隔(實際過程更為復(fù)雜,這里只做簡單講解)。
并行復(fù)制
在MySQL5.6之前的版本中,從庫同步數(shù)據(jù)時,所有數(shù)據(jù)同步工作都是基于單線程完成的,也就是不管主庫上的數(shù)據(jù)是不是多線程并發(fā)寫入的,從庫上只會有一條SQL線程來執(zhí)行解析執(zhí)行工作。
到了MySQL5.6之后,引入了并行復(fù)制的思想,但5.6中的并行復(fù)制極其雞肋,基本無人問津,因為是基于庫級別的并行復(fù)制,也就是一個從節(jié)點對應(yīng)多個主節(jié)點時,有幾個主節(jié)點就開幾條SQL線程去解析并寫入數(shù)據(jù),即多主一從架構(gòu)中才會用到。
因為官方最初在實現(xiàn)并行復(fù)制時,一直糾結(jié)鎖沖突的問題,所以為了防止并行執(zhí)行時出現(xiàn)數(shù)據(jù)沖突,就造出了上面那種庫級別的并行復(fù)制,為啥要糾結(jié)鎖/數(shù)據(jù)沖突呢?
比如從庫I/O線程在主庫中請求了100條記錄回去,從庫中開100條SQL線程解析并執(zhí)行這些記錄,如果其中有兩條記錄操作的是同一條數(shù)據(jù),就會出現(xiàn)鎖沖突問題。
- 但上述原因不是最主要的,最主要的是并發(fā)執(zhí)行的順序問題,如果主庫上對于一條數(shù)據(jù)是先改后刪,從庫在并發(fā)執(zhí)行時,因為多線程執(zhí)行的無序性,把執(zhí)行順序改為了先刪后改,這顯然就會導(dǎo)致數(shù)據(jù)沖突,因此變更操作很難實現(xiàn)并行復(fù)制。
- 到了MySQL5.7中,才基于組復(fù)制技術(shù)實現(xiàn)了真正意義上的并行復(fù)制,因為能夠在同一時間內(nèi)提交的事務(wù),絕對是不存在鎖沖突的,所以可以開啟多條線程同時執(zhí)行一個組中不同的事務(wù),但這個思想是從MariaDB中照抄過來的~
一句話來總結(jié)就是:主庫上是咋樣并發(fā)寫入數(shù)據(jù)的,從庫也會開啟對應(yīng)的線程數(shù)去并發(fā)寫入。
在5.7中官方為這種機(jī)制命名為enhanced multi-threaded slave,簡稱MTS機(jī)制,同時為了兼容5.6版本中的并行復(fù)制,又多加入了一個slave-parallel-type參數(shù):
- DATABASE:默認(rèn)的并行復(fù)制模式,表示基于庫級別的來完成并行復(fù)制。
- LOGICAL_CLOCK:表示基于組提交的方式來完成并行復(fù)制。
并行復(fù)制出現(xiàn)的意義是什么?
能夠在很大程度上提升從庫復(fù)制數(shù)據(jù)的速度,也就是能夠讓從庫的數(shù)據(jù)實時性提升,尤其是無損復(fù)制模式中,主節(jié)點需要等待從節(jié)點的ACK才會真正提交事務(wù),從庫使用并行復(fù)制后,能夠在一定程度上解決從庫的復(fù)制延遲問題。
不過雖然5.7中的并行復(fù)制,在一定程度上解決了原有的從庫延遲問題,但如果一個新的從節(jié)點加入集群時,因為要從頭開始同步數(shù)據(jù),這種并行復(fù)制的模式依舊存在效率問題,而到了MySQL8.0中,對于并行復(fù)制技術(shù)提出了真正的解決之道,也就是基于writeset的MTS技術(shù)。
主從數(shù)據(jù)一致性的解決方案
讀寫分離數(shù)據(jù)一致性場景:一個用戶將個人信息修改后,然后再次查看時,發(fā)現(xiàn)個人信息依舊是修改之前的原數(shù)據(jù),這時用戶就有可能再次修改,經(jīng)過反反復(fù)復(fù)多次修改后,用戶發(fā)現(xiàn)依舊未生效
想要解決上述這種讀寫分離導(dǎo)致的數(shù)據(jù)不一致性,主要有四種解決方案:
業(yè)務(wù)邏輯做改變、復(fù)制方式做更改、數(shù)據(jù)庫架構(gòu)做調(diào)整、引入第三方中間件。
改變業(yè)務(wù)邏輯
- 對業(yè)務(wù)做一定更改,比如當(dāng)用戶立即修改數(shù)據(jù)后,因為在從庫讀不到數(shù)據(jù),所以先顯示一個審核狀態(tài),這樣能夠給出用戶的反饋,從而避免用戶再次重復(fù)操作
- 這種方式屬于和數(shù)據(jù)不一致妥協(xié)的方案,接受一定的數(shù)據(jù)延遲,不過這種方式并不適用于一些對數(shù)據(jù)實時性要求較高的場景
更改復(fù)制方式
- 在之前曾聊過MySQL四種數(shù)據(jù)同步復(fù)制的方式,即全同步、異步、半同步與無損復(fù)制,MySQL默認(rèn)會是異步復(fù)制模式,即主節(jié)點寫入數(shù)據(jù)后會立即返回成功的狀態(tài)給客戶端,這樣能夠確保性能達(dá)到最佳,但如果對實時性要求較高,可以將其改為全同步或半同步模式。
調(diào)整數(shù)據(jù)庫架構(gòu)
- 如果無法接受主從架構(gòu)帶來的短期數(shù)據(jù)不一致,那可以升級服務(wù)器硬件,并將架構(gòu)恢復(fù)成單庫架構(gòu),所有讀寫操作都走單庫完成,這就自然不會出現(xiàn)數(shù)據(jù)不一致問題。
- 但如果升級硬件配置后,無法承載客戶端的訪問壓力時,可將整體架構(gòu)升級到分庫分表架構(gòu),制定好合適的分片策略和路由鍵,每次讀寫數(shù)據(jù)都根據(jù)業(yè)務(wù)不同,操作不同的庫。
引入第三方中間件
- 前面聊到的三種方案,多多少少都存在一些局限性,因為要么接受數(shù)據(jù)不一致、要么損失性能、要么使用更高規(guī)模的架構(gòu)處理,但這些方案似乎都存在令人不能接受的后患,那有沒有一種萬全之策來解決這個問題呢?答案是有的,就是引入Canal中間件來監(jiān)控主節(jié)點的Bin-log日志。
- 在之前講主從同步數(shù)據(jù)原理時,曾講到過,主節(jié)點上存在一個log dump線程會監(jiān)聽Bin-log日志,當(dāng)日志出現(xiàn)變更時會通知從節(jié)點來拉取數(shù)據(jù),而Canal的思想也是一樣的,會監(jiān)控主節(jié)點的Bin-log日志,當(dāng)發(fā)生變更時,就直接去拉取數(shù)據(jù),然后直接推送給從節(jié)點寫入。
- 但這種方式也無法做到真正的數(shù)據(jù)實時性,畢竟Canal監(jiān)聽變更、拉取數(shù)據(jù)、推送數(shù)據(jù)都需要時間,這部分的時間開銷必然存在,只是它會比從庫去主庫上拉取,速度會更快一些罷了。
- 一般企業(yè)內(nèi)部都會引入Canal來解決數(shù)據(jù)不一致問題,因為它不僅僅只能解決主從延遲問題,還能解決MySQL-ES、MySQL-Redis.....等多種數(shù)據(jù)不一致的場景
- 也可以制定某些敏感數(shù)據(jù)走主庫查詢,這樣能夠確保數(shù)據(jù)的實時性,但容易模糊讀寫分離的界限,不過因為不需要引入額外的技術(shù),所以在某些情況下也是個不錯的方案。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
ERROR 1045 (28000): Access denied for user ''''root''''@''''
這篇文章主要介紹了Linux下數(shù)據(jù)庫報ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)實用解決方案,希望能對大家有幫助。2017-10-10
怎么重置mysql的自增列AUTO_INCREMENT初時值
怎么重置mysql的自增列想必有很多的朋友都不會吧,下面與大家分享下常用的幾種方法,不懂的朋友可以了解下哈,希望對大家有所幫助2013-06-06
MySQL數(shù)據(jù)庫服務(wù)器端核心參數(shù)詳解和推薦配置
MySQL手冊上也有服務(wù)器端參數(shù)的解釋,以及參數(shù)值的相關(guān)說明信息,現(xiàn)針對我們大家重點需要注意、需要修改或影響性能 的服務(wù)器端參數(shù),作其用處的解釋和如何配置參數(shù)值的推薦,此事情拖了不少時間,為方便大家?guī)兔m錯2011-12-12
windows10系統(tǒng)安裝mysql-8.0.13(zip安裝) 的教程詳解
這篇文章主要介紹了windows10安裝mysql-8.0.13(zip安裝) 的教程,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-11-11
mysql5.x升級到mysql5.7后導(dǎo)入之前數(shù)據(jù)庫date出錯的快速解決方法
這篇文章主要介紹了mysql5.x升級到mysql5.7后導(dǎo)入之前數(shù)據(jù)庫date出錯的快速解決方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09

