揭秘MySQL主從復(fù)制:數(shù)據(jù)同步的幕后故事
MySQL 的主從復(fù)制基于 binlog 實(shí)現(xiàn),其主要過程如下:
圖片
- 從服務(wù)器在開啟主從復(fù)制后,將會(huì)創(chuàng)建兩個(gè)線程:I/O 線程與 SQL 線程。
- 從服務(wù)器的 I/O 線程會(huì)嘗試與主服務(wù)器建立連接,主服務(wù)器中則有一個(gè)專門與從服務(wù)器的 I/O 線程進(jìn)行交互的 binlog dump 線程。
- 從服務(wù)器的 I/O 線程會(huì)向主服務(wù)器的 dump 線程指明其接收 binlog 的起始位置。
- 在主服務(wù)器的更新過程中,更改記錄會(huì)被保存到其 binlog 中,依據(jù)不同的 binlog 格式,記錄的內(nèi)容可能有所不同。
- 當(dāng) dump 線程檢測(cè)到 binlog 發(fā)生變化時(shí),將從指定位置開始讀取內(nèi)容,并由從服務(wù)器的 I/O 線程將其拉取過來。
這里需要注意的是,盡管某些資料提到主服務(wù)器向從服務(wù)器推送數(shù)據(jù),實(shí)際上,過程是從服務(wù)器主動(dòng)向主服務(wù)器拉取的。(https://dev.mysql.com/doc/refman/8.0/en/replication-implementation.html)
拉的模式,從庫可以自行管理同步進(jìn)度和處理延遲。
- 從服務(wù)器的 I/O 線程在接收到通知事件后,會(huì)將內(nèi)容保存至 relay log 中。
- 從服務(wù)器的 SQL 線程則會(huì)不斷讀取自身的 relay log,將內(nèi)容解析為具體操作,并將其寫入數(shù)據(jù)表中。
復(fù)制方式
MySQL 目前支持多種復(fù)制方式,包括全同步復(fù)制、異步復(fù)制和半同步復(fù)制。
異步復(fù)制:這是 MySQL 的默認(rèn)復(fù)制方式。在異步復(fù)制中,主庫在執(zhí)行完事務(wù)后會(huì)立即向客戶端返回,無需關(guān)心從庫是否完成該事務(wù)的執(zhí)行。這種方式可能導(dǎo)致問題:當(dāng)主庫發(fā)生故障時(shí),盡管事務(wù)已執(zhí)行完畢,但數(shù)據(jù)可能尚未同步至從庫,導(dǎo)致從庫在升級(jí)為主庫時(shí)丟失此次事務(wù)的變更內(nèi)容。
全同步復(fù)制:在全同步復(fù)制模式下,主庫在完成事務(wù)后,會(huì)等待所有從庫完成數(shù)據(jù)復(fù)制后,才向客戶端反饋。這種方式雖然提高了安全性,但性能較差,尤其在從庫數(shù)量較多時(shí),整個(gè)過程將顯得更加漫長(zhǎng)。
半同步復(fù)制:半同步復(fù)制介于全同步與異步之間。當(dāng)主庫執(zhí)行完事務(wù)后,它不會(huì)立即反饋給客戶端,而是等待至少一個(gè)從庫完成接收事件后再反饋。在這一方案中,主庫會(huì)在事務(wù)提交的兩個(gè)階段完成后,等待從庫接收到 binlog 后,再返回成功。
在上面這篇中所繪制的圖示中,如果將半同步復(fù)制的過程也納入其中,那么圖示將會(huì)變?yōu)椋?/p>
圖片