一張圖讓你牢記MySQL主從復(fù)制原理|原創(chuàng)
本文深入淺出的講解了MySQL面試中的必考內(nèi)容——主從同步原理,牢記文中的主從同步流程圖即可!
為什么需要主從復(fù)制?
1、讀寫分離,增強(qiáng)MySQL數(shù)據(jù)庫的可用性。
2、做數(shù)據(jù)的熱備。
3、架構(gòu)的擴(kuò)展。業(yè)務(wù)量越來越大,I/O訪問頻率過高,單機(jī)無法滿足,此時(shí)做多庫的存儲(chǔ),降低磁盤I/O訪問的頻率,提高單個(gè)機(jī)器的I/O性能。
什么是mysql的主從復(fù)制?
MySQL 主從復(fù)制是指數(shù)據(jù)可以從一個(gè)MySQL數(shù)據(jù)庫服務(wù)器主節(jié)點(diǎn)復(fù)制到一個(gè)或多個(gè)從節(jié)點(diǎn)。MySQL 默認(rèn)采用異步復(fù)制方式,這樣從節(jié)點(diǎn)不用一直訪問主服務(wù)器來更新自己的數(shù)據(jù),數(shù)據(jù)的更新可以在遠(yuǎn)程連接上進(jìn)行,從節(jié)點(diǎn)可以復(fù)制主數(shù)據(jù)庫中的所有數(shù)據(jù)庫或者特定的數(shù)據(jù)庫,或者特定的表。

主從復(fù)制搭建
主從復(fù)制的搭建我已經(jīng)寫過了,詳細(xì)可以看這篇文章:

快速入門Mycat及主從搭建指南
MySQL 主從復(fù)制原理
在多個(gè)源的復(fù)制中,每一個(gè)復(fù)制源都會(huì)打開一個(gè)復(fù)制通道,這是一個(gè)長鏈接。并且每個(gè)復(fù)制源都有自己的 IO線程、一個(gè)或者多個(gè)點(diǎn) SQL 線程以及 realy log。復(fù)制源接收到事務(wù)時(shí)會(huì)將其添加到relay log 中,然后通過SQL thread執(zhí)行。相關(guān)官方文檔如下:
In MySQL multi-source replication, a replica opens multiple replication channels, one for each replication source server. The replication channels represent the path of transactions flowing from a source to the replica. Each replication channel has its own receiver (I/O) thread, one or more applier (SQL) threads, and relay log. When transactions from a source are received by a channel's receiver thread, they are added to the channel's relay log file and passed through to the channel's applier threads. This enables each channel to function independently.
主從復(fù)制應(yīng)該是分為第一次建立連接和增量數(shù)據(jù)同步過程。
第一次建立連接
備庫 B 跟主庫 A 之間維持了一個(gè)長連接。主庫 A 內(nèi)部有一個(gè)io_thread線程,專門用于服務(wù)備庫 B 的這個(gè)長連接。一個(gè)事務(wù)日志同步的完整過程是這樣的:
1.在備庫 B 上通過 change master 命令,設(shè)置主庫 A 的 IP、端口、用戶名、密碼,以及要從哪個(gè)位置開始請(qǐng)求 binlog,這個(gè)位置包含文件名和日志偏移量。
CHANGE MASTER TO MASTER_HOST='192.168.56.104',MASTER_USER='root',MASTER_PASSWORD='qwer_123',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
2.在備庫 B 上執(zhí)行 start slave 命令,這時(shí)候備庫會(huì)啟動(dòng)兩個(gè)線程,就是圖中的 io_thread 和 sql_thread。其中 io_thread 負(fù)責(zé)與主庫建立連接。
3.主庫 A 校驗(yàn)完用戶名、密碼后,開始按照備庫 B 傳過來的位置,從本地讀取 binlog,發(fā)給備庫 B。
4.備庫 B 拿到 binlog 后,寫到relay log(中繼日志)中。
5.備庫的 sql_thread 讀取 relay log,解析出日志里的命令,并且回放執(zhí)行。
增量同步詳細(xì)流程
詳細(xì)過程如下:
1.客戶端發(fā)起 update 請(qǐng)求,MySQL server 端收到請(qǐng)求。
2.生成被修改數(shù)據(jù)行對(duì)應(yīng)的 unodo log。
3.執(zhí)行update成功寫入內(nèi)存。
4.InnboDB 生成 redo log ,此時(shí)處于 prepare階段。
5.server 層生成binlog,事務(wù)提交時(shí)binlog做持久化,此時(shí)binlog便可以開始被同步到從庫了。
6.redo log 做磁盤持久化,同時(shí)向客戶端返回update的執(zhí)行新結(jié)果(默認(rèn)異步復(fù)制,以后會(huì)講)。
7.主庫發(fā)送生成的 binlog 數(shù)據(jù)。
8.從庫的io_thread處理Maste傳輸過來的數(shù)據(jù),保存為relay log。從庫服務(wù)器會(huì)在一定時(shí)間間隔內(nèi)對(duì)master二進(jìn)制日志進(jìn)行探測(cè)其是否發(fā)生改變,如果發(fā)生改變,則開始一個(gè)I/OThread請(qǐng)求master二進(jìn)制事件
9.SQL thread 讀取relay log,解析并且在從庫中重放執(zhí)行,數(shù)據(jù)同步完成。最后I/OThread和SQLThread將進(jìn)入睡眠狀態(tài),等待下一次被喚醒。
MySQL 如何知道 binlog 是完整的?
從庫在解析的時(shí)候如何知道一個(gè)事務(wù)是完整的?因?yàn)橐粋€(gè)事務(wù)的 binlog 是有完整格式的:statement 格式的 binlog,最后會(huì)有 COMMIT 標(biāo)記;row 格式的 binlog,最后會(huì)有一個(gè) XID event。
如果覺得對(duì)你有幫助,歡迎評(píng)論或分享,感謝閱讀!
