標籤:
一、緣由
最近在研究MySQL的複製及各種高可用架構,發現基本都是基於主從複製的組合。而主從複製是基於binary log的,
故這裡就詳細介紹下基於binary log event(二進位日誌事件)複製的原理。
主從複製有實現兩種方法:傳統複製方式(基於server_id)和GTID(全域事務ID)。(MySQL5.6以後支援)
二、原理詳解
1.簡單來說(三個線程三個步驟):
1)主伺服器Master將資料庫的改變寫入二進位記錄檔,並維護一個等待從伺服器串連的線程binlog_dump;
2)從伺服器Slave會啟動一個線程(IO Thread)和主伺服器Master的binlog_dump線程建立串連,然後將資料
讀取到從伺服器Slave,並寫入中繼日誌(Relay log);
3)從伺服器Slave另一個線程(SQL thread)會從中繼日誌中讀取資料,並在從資料庫應用程式更新,完成資料同步。
2.細節實現:
MySQL使用3個線程來執行複製功能(一個在主伺服器,兩個在從伺服器)。
1)當從伺服器發出start slave時,從伺服器Slave建立一個I/0線程,去串連主伺服器Master並讓他發送記錄在其二進位日誌中的語句。
2)主伺服器Master建立一個線程Binlog Dump將二進位日誌中的內容發送到從伺服器Slave。(可在show processlist中看到該線程)
3)從伺服器Slave I/O線程讀取主伺服器Binlog Dump線程發送過來的內容並將資料拷貝到從伺服器資料目錄中的中繼日誌中Relay log。
4)從伺服器Slave建立SQL線程,用於讀取中繼日誌並執行日誌中包含的更新。
在從伺服器上讀取和執行更新語句被分成兩個獨立的任務,當從伺服器啟動時,其I/O線程可以很快地從主伺服器Master索取所有
二進位日誌內容,同時交由SQL線程來更新應用到從庫(會有點慢)。
3.複製線程的狀態
通過show processlist可以看到三個線程的狀態,show slave status 可以看到IO、SQL線程的狀態。常見的狀態有:
1)主伺服器Binlog Dump線程狀態:
Master has sent all binlog to slave; waiting for binlog to be updated
線程已經從二進位日誌中讀取所有主要的更新並已經發送到從伺服器。
線程現在正空閑,等待由主伺服器上新的更新導致的出現在二進位記錄檔中新的事務。
2)從伺服器I/O線程狀態:
Waiting for master to send event
線程已經串連上主伺服器,正在等待二進位日誌事件到達。如果主伺服器正空閑,會持續較長時間。
如果等待持續slave_net_timeout秒,則發生逾時。此時,線程認為串連中斷並企圖重新串連。
3)從伺服器SQL線程狀態:
Reading event from the relay log
線程已經從中繼日誌中讀取一個事件,可以對事件進行處理了。
Slave has read all relay log;waiting for the slave I/O thread to update it
線程已經處理了中繼記錄檔中的所有事件,現在正在等待I/O線程將新事件寫入中繼日誌。
4.複製過程中狀態的保持:
從伺服器通過在my.cnf設定如下參數,將主從狀態儲存在mysql庫的表中slave_master_info、slave_relay_log_info。
下次從伺服器啟動時,讀取這個表來確定它已經從主伺服器讀取了多少二進位日誌,已經自己處理裝機日誌的程度。
relay_log_info_repository = TABLE
master_info_repository = TABLE
[MySQL] 主從複製原理