主從復制原理
1.數據庫有個bin-log二進制文件,記錄了所有sql語句。
2.我們的目標就是把主數據庫的bin-log文件的sql語句復制過來。
3.讓其在從數據的relay-log重做日志文件中再執行一次這些sql語句即可。
4.下面的主從配置就是圍繞這個原理配置
5.具體需要三個線程來操作:
1.binlog輸出線程:每當有從庫連接到主庫的時候,主庫都會創建一個線程然后發送binlog內容到從庫。在從庫里,當復制開始的時候,從庫就會創建兩個線程進行處理:
2.從庫I/O線程:當START SLAVE語句在從庫開始執行之后,從庫創建一個I/O線程,該線程連接到主庫並請求主庫發送binlog里面的更新記錄到從庫上。從庫I/O線程讀取主庫的binlog輸出線程發送的更新並拷貝這些更新到本地文件,其中包括relay log文件。
3.從庫的SQL線程:從庫創建一個SQL線程,這個線程讀取從庫I/O線程寫到relay log的更新事件並執行。
可以知道,對於每一個主從復制的連接,都有三個線程。擁有多個從庫的主庫為每一個連接到主庫的從庫創建一個binlog輸出線程,每一個從庫都有它自己的I/O線程和SQL線程。
步驟一:主庫db的更新事件(update、insert、delete)被寫到binlog
步驟二:從庫發起連接,連接到主庫
步驟三:此時主庫創建一個binlog dump thread線程,把binlog的內容發送到從庫
步驟四:從庫啟動之后,創建一個I/O線程,讀取主庫傳過來的binlog內容並寫入到relay log.
步驟五:還會創建一個SQL線程,從relay log里面讀取內容,從Exec_Master_Log_Pos位置開始執行讀取到的更新事件,將更新內容寫入到slave的db.
一、異步復制
在異步復制中,主庫執行完操作后,寫入binlog日志后,就返回客戶端,這一動作就結束了,並不會驗證從庫有沒有收到,完不完整,所以這樣可能會造成數據的不一致。
說到底,復制過程中數據是否一致,主要取決於Binlog日志的安全性與完整性
在MySQL中,有sync_binlog=n這一參數,他的值表示每進行n次事務提交,MySQL就將Binlog刷新到磁盤。如果這個值為1,就代表每提交一次事務(SQL),就將Binlog往磁盤刷新一次,這樣一來,就算數據庫宕機了,那么最多只能損失一次事務的數據。
但是,一旦多個事務並發提交時,由於受sync_binlog的限制,MySQL只能按順序來處理這些請求,另外,高頻率的刷新binlog對IO的影響也很大,進一步影響了數據庫的性能,所以,一般這個值都設為0或者其他值,在數據的安全性和高並發下的性能之間取得一個平衡。
為了更加有效的保護Binlog的安全性和完整性,MySQL5 .5之后引入了半同步復制
二、半同步復制
在異步復制中,我們遇到的一個主要問題就是,在復制過程當中,主庫不會去驗證Binlog有沒有成功復制到從庫,那如果主庫提交一個事務並寫入Binlog中后,當從庫還沒有從主庫得到Binlog時,主庫宕機了或因磁盤損壞等故障導致該事務的Binlog丟失了,那從庫就不會得到這個事務,也就造成了主從數據的不一致。
而半同步復制,當主庫每提交一個事務后,不會立即返回,而是等待其中一個從庫接收到Binlog並成功寫入Relay-log中才返回客戶端,所以這樣就保證了一個事務至少有兩份日志,一份保存在主庫的Binlog,另一份保存在其中一個從庫的Relay-log中,從而保證了數據的安全性和一致性。
另外,在半同步復制時,如果主庫的一個事務提交成功了,在推送到從庫的過程當中,從庫宕機了或網絡故障,導致從庫並沒有接收到這個事務的Binlog,此時主庫會等待一段時間(這個時間由rpl_semi_sync_master_timeout的毫秒數決定),如果這個時間過后還無法推送到從庫,那MySQL會自動從半同步復制切換為異步復制,當從庫恢復正常連接到主庫后,主庫又會自動切換回半同步復制。
半同步復制的“半”體現在,雖然主從庫的Binlog是同步的,但主庫不會等待從庫執行完Relay-log后才返回,而是確認從庫接收到Binlog,達到主從Binlog同步的目的后就返回了,所以從庫的數據對於主庫來說還是有延時的,這個延時就是從庫執行Relay-log的時間。所以只能稱為半同步。
具體操作詳解見下鏈接地址:
————————————————
版權聲明:本文為CSDN博主「Pursue happiness」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/keil_wang/article/details/88669587