上一篇文章里面,講到了遇到mysql主從同步延遲的坑,對于這次的坑多說兩句,以前也看過這樣的例子,也知道不能夠寫完之后馬上更新,但是真正開發(fā)的時候還是沒有注意到這一點,道理大家都懂,但是還是會犯錯,只有等到自己親生體驗到該錯誤之后,才真正的掌握到該道理。

經歷過一次mysql主從延遲之后,就開始思考,主從復制是什么東西?它是怎么實現(xiàn)的呢?它的原理是什么?于是乎就開始查閱資料、文章,現(xiàn)將自己理解到的內容總結在此,加深印象。

為什么要做主從復制?

1、在業(yè)務復雜的系統(tǒng)中,有這么一個情景,有一句sql語句需要鎖表,導致暫時不能使用讀的服務,那么就很影響運行中的業(yè)務,使用主從復制,讓主庫負責寫,從庫負責讀,這樣,即使主庫出現(xiàn)了鎖表的情景,通過讀從庫也可以保證業(yè)務的正常運作。

2、做數(shù)據的熱備

3、架構的擴展。業(yè)務量越來越大,I/O訪問頻率過高,單機無法滿足,此時做多庫的存儲,降低磁盤I/O訪問的頻率,提高單個機器的I/O性能。

mysql主從復制的原理是什么?

binlog: binary log,主庫中保存更新事件日志的二進制文件。

主從復制的基礎是主庫記錄數(shù)據庫的所有變更記錄到binlog。binlog是數(shù)據庫中保存配置中過期時間內所有修改數(shù)據庫結構或內容的一個文件。如果過期時間是10d的話,那么就是最近10d的數(shù)據庫修改記錄。

mysql主從復制是一個異步的復制過程,主庫發(fā)送更新事件到從庫,從庫讀取更新記錄,并執(zhí)行更新記錄,使得從庫的內容與主庫保持一致。

在主庫里,只要有更新事件出現(xiàn),就會被依次地寫入到binlog里面,是之后從庫連接到主庫時,從主庫拉取過來進行復制操作的數(shù)據源。

binlog輸出線程。每當有從庫連接到主庫的時候,主庫都會創(chuàng)建一個線程然后發(fā)送binlog內容到從庫。
對于每一個即將發(fā)送給從庫的sql事件,binlog輸出線程會將其鎖住。一旦該事件被線程讀取完之后,該鎖會被釋放,即使在該事件完全發(fā)送到從庫的時候,該鎖也會被釋放。

在從庫里,當復制開始的時候,從庫就會創(chuàng)建兩個線程進行處理:

從庫I/O線程。當START SLAVE語句在從庫開始執(zhí)行之后,從庫創(chuàng)建一個I/O線程,該線程連接到主庫并請求主庫發(fā)送binlog里面的更新記錄到從庫上。
從庫I/O線程讀取主庫的binlog輸出線程發(fā)送的更新并拷貝這些更新到本地文件,其中包括relay log文件。

從庫的SQL線程。從庫創(chuàng)建一個SQL線程,這個線程讀取從庫I/O線程寫到relay log的更新事件并執(zhí)行。

可以知道,對于每一個主從復制的連接,都有三個線程。擁有多個從庫的主庫為每一個連接到主庫的從庫創(chuàng)建一個binlog輸出線程,每一個從庫都有它自己的I/O線程和SQL線程。

從庫通過創(chuàng)建兩個獨立的線程,使得在進行復制時,從庫的讀和寫進行了分離。因此,即使負責執(zhí)行的線程運行較慢,負責讀取更新語句的線程并不會因此變得緩慢。比如說,如果從庫有一段時間沒運行了,當它在此啟動的時候,盡管它的SQL線程執(zhí)行比較慢,它的I/O線程可以快速地從主庫里讀取所有的binlog內容。這樣一來,即使從庫在SQL線程執(zhí)行完所有讀取到的語句前停止運行了,I/O線程也至少完全讀取了所有的內容,并將其安全地備份在從庫本地的relay log,隨時準備在從庫下一次啟動的時候執(zhí)行語句。

網友評論