MySQL主備復制原理
更新時間 2023-07-04 19:43:09
最近更新時間: 2023-07-04 19:43:09
分享文章
本文介紹了MySQL主備復制原理。
MySQL主備復制原理說明
MySQL復制是基于復制源服務器在其二進制日志(下稱binlog)中跟蹤對其數據庫的所有更改(增、刪、改等)。binlog作為從服務器啟動那一刻起修改數據庫結構或內容(數據)的所有事件的書面記錄。通常,SELECT不記錄語句是因為它們既不修改數據庫結構也不修改數據本身。
連接到源的每個副本都請求binlog的副本。也就是說,它從源中拉取數據,而不是源將數據推送到副本。副本還執行它接收到的binlog中的事件。這具有重復原始更改的效果,就像它們在源上所做的一樣。創建表或修改其結構,并根據最初在源上所做的更改插入、刪除和更新數據。
因為每個副本都是獨立的,所以來自源的binlog的更改的重播獨立發生在連接到源的每個副本上。此外,因為每個副本僅通過從源請求它來接收binlog的副本,副本能夠按照自己的節奏讀取和更新數據庫的副本,并且可以隨意啟動和停止復制過程而不會影響在源端或副本端更新到最新數據庫狀態的能力。
主備復制流程說明:

- 主庫節點中每當有數據進行DML操作時,事務會按照binlog格式將DML操作以event的形式寫入到主節點的binlog中。DML包括:Insert, Delete, Update等。
- 備庫節點連接主庫節點時,有多少個備節點就會創建多少個binlog dump線程。
- 當主庫節點的binlog發生變化時,binlog dump線程會通知備節點(若多個備庫則通知所有備節點),并將相應的binlog內容推送給備庫節點。
- 備庫節點的I/O thread進程收到binlog后,會將日志包含的內容寫入本地中繼日志(下稱relay log)。
- 備庫節點的SQL thread會讀取I/O thread寫入的relay log并根據relay log中記錄的event內容生成相應的DML語句,回放入備庫中,完成整個主備復制流程。
主要源碼說明:
/*
The pseudo code to compute Seconds_Behind_Master: 信息來自源碼sql/rpl_replica.cc
if (SQL thread is running)
//如果SQL thread啟動
{
if (SQL thread processed all the available relay log)
? //當IO thread拉取主庫binlog的位置和SQL thread應用的relay log相對于主庫binlog的位置相等時
? {
? if (IO thread is running)
? //如果IO thread啟動,設置延遲為0
? print 0;
? else
? //如果未啟動,設置延遲為NULL
? print NULL;
? }
? else
? //如果SQL thread沒有應用完所有IO thread寫入的event時,需要計算Seconds_Behind_Master
? compute Seconds_Behind_Master;
}
else
? //如果SQL thread也沒啟動,則設置為NULL
? print NULL;
*/
Seconds_Behind_Master的計算公式:Seconds_Behind_Master = time(0) - last_master_timestamp - clock_diff_with_master。
公式變量解釋:
- time(0):當前備庫節點服務器的系統時間。
- last_master_timestamp:備庫節點在回放relay log中的event過程中的計算和更新,該變量可理解為備庫節點SQL thread處理中事務在主庫節點中的執行時間。
- clock_diff_with_master:備庫節點的系統時間和主庫節點服務器系統時間的差值,一般為0。如果主備節點系統時間不一致,那計算出的備庫節點復制時延會不準確。
綜上所述:Seconds_Behind_Master = 當前備庫節點服務器的系統時間 - 備庫節點SQL線程處理中事務在主庫節點的執行時間 - 備庫節點的系統時間和主庫節點服務器系統時間的差值。