MySQL主從複製歷程

lhrbest發表於2020-11-16


在很多場景下,MySQL 的高可用都是藉助主從複製實現的,而 MySQL 複製不斷的演進,也使得她越來越受歡迎。


1 三種日誌格式對複製的影響

1.1 開始支援複製

MySQL 從 3.23 版本開始支援複製,但是在 5.1.5 之前只支援 statement 格式的複製,儘管這種模式下,binlog 日誌量相對比較少,但是涉及到跨庫更新、或者使用結果不確定的函式時,比如 UUID(),容易出現主從資料不一致的情況。


1.2 開始支援 Row 格式的複製

從 MySQL 5.1.5 開始,新增了 Row 格式,日誌中會記錄每一行資料被修改的形式,因此 Row 格式下的複製,主從之間的資料一致性保障得到了大幅度提升,但是缺點是 binlog 日誌量相對 statement 較多。


1.3 新增 mixed 格式

從 MySQL 5.1.8 開始新增 mixed 格式,當可能造成主從資料不一致的 SQL 時,binlog 使用 row 格式記錄,否則使用 statement 格式記錄。顯然這種格式下,日誌量是介於 statement 和 row 格式之間的。


2 半同步複製

2.1 非同步複製

傳統的 MySQL 複製為非同步複製,其原理如下:

  • 在主庫開啟 binlog 的情況下;

  • 如果主庫有變更操作,會記錄到 binlog 中;

  • 主庫透過 IO 執行緒把 binlog 裡面的內容傳給從庫的中繼日誌(relay log)中;

  • 主庫給客戶端返回 commit 成功(這裡不管從庫是否已經收到了事務的 binlog);

  • 從庫的 SQL 執行緒負責讀取它的 relay log 裡的資訊並應用到從庫資料庫中。

其過程如下圖:

MySQL主從複製歷程
在非同步複製下,假如配置了自動切換的前提下,主庫突然當機,然後從提升為主時,原來主庫上可能有一部分已經完成提交的資料還沒來得及傳送到從庫,就可能產生資料丟失。為了解決這個問題,在 MySQL 5.5 版本中引入了半同步複製。下面來看下半同步複製的原理。

2.2 半同步複製

半同步複製原理如下:

  • 在主庫開啟 binlog 的情況下;
  • 如果主庫有增刪改的語句,會記錄到 binlog 中;
  • 主庫透過 IO 執行緒把 binlog 裡面的內容傳給從庫的中繼日誌(relay log)中;
  • 從庫收到 binlog 後,傳送給主庫一個 ACK,表示收到了;
  • 主庫收到這個 ACK 以後,才能給客戶端返回 commit 成功;
  • 從庫的 SQL 執行緒負責讀取它的 relay log 裡的資訊並應用到從庫資料庫中。

其過程如下圖:
MySQL主從複製歷程
跟傳統非同步複製相比,半同步複製保證了所有客戶端傳送過確認提交的事務,從庫都已經收到這個日誌了。
但是這種模式下,實際上主庫已經將該事務 commit 到事務引擎層,只是在等待返回而已,而此時其他 session 已經可以看到資料發生了變化,如果此時主庫當機,有可能從庫還沒寫 Relay log,就會發生其他 session 切換前後查詢的資料不一致的情況。
因此,從 MySQL 5.7 開始,引入了增強半同步複製(無損複製)。

2.3 增強半同步複製

增強半同步複製(也叫無損複製)是在半同步複製基礎上做了微調,即主庫寫資料到 binlog 後,就開始等待從庫的應答 ACK,直到至少一個從庫寫入 Relay log 並進行資料落盤後,才返回給主庫訊息,通知主庫可以執行 commit 操作了,然後主庫開始提交到事務引擎層。
但是,增強半同步複製其實也是存在問題的,假設有一個事務寫 binlog 後 crash 了,事務還沒有傳送給從庫,這時從庫提升為主庫,對客戶端來說,資料沒問題的,因為主庫還沒給客戶端返回 commit;但是當老的主庫恢復後,由於這個事務的 binlog 已經寫入磁碟了,因此沒辦法回滾,在 crash recover 的機制下,會把這些事務重新提交,這就導致老的主庫比新的主庫多事務的情況。
因此又出現了一種複製形式--組複製。

3 組複製

MySQL 5.7 推出了組複製(MySQL Group Replication,簡稱:MGR),是基於內建的主從複製的架構實現的,主要在事務提交的過程中,嵌入單獨的 binlog 封裝邏輯,並透過專門的複製通道進行資料傳輸,
Group Replication 複製外掛使用 Paxos 協議的原子廣播特性,來保證在叢集內的大多數節點都能接收到資料包,當資料節點接收到 write set 之後,每個節點上按照相同的規則對事務進行排序,並進行衝突檢測。
對於 master,當衝突檢測透過之後,資料變更寫入自身的 binlog 中,然後進行儲存引擎層的提交(如果發現事務衝突,則進行事務回滾);
對於 slave,當衝突檢測透過之後,就把主庫發來的 binlog 寫入自身的 relay log 中,然後 sql 執行緒讀取 relay log 進行重放,並把重放的 binlog 日誌寫入自身的 binlog 中,然後儲存引擎內部進行提交(如果發現事務衝突,則丟棄主庫傳送過來的 binlog 日誌) 。
MySQL主從複製歷程
那麼組複製如何處理故障轉移的呢?
假設 3 個節點的叢集,當寫節點 crash 之後,叢集內部重新選舉一個節點作為新的寫節點,整個寫請求故障轉移過程都是 Group Replication 內部自動完成(當然,寫請求具體傳送到哪個節點,還是需要更新 DNS 解析或者使用其它外掛),解決了某個節點掛了如何踢掉或者恢復後如何加入叢集(非同步複製和半同步複製都需要人為干預或者依賴其他外掛)。 

4 並行複製

4.1 MySQL 5.6 的並行複製

在傳統的複製模式下,我們也許經常會遇到主從延遲的場景。這是因為在 MySQL 5.6 之前,MySQL 只支援單執行緒複製。
從 MySQL 5.6 版本開始,支援並行複製策略,但是隻支援庫級別的。如果表都集中在一個 DB 裡,或者熱點表集中在一個庫中,那就沒有什麼效果了。

4.2 MySQL 5.7 的並行複製

由引數:slave-parallel-type 控制並行複製策略。
配置為 DATABASE,表示使用 MySQL 5.6 版本的按庫並行策略;
配置為 LOGICAL_CLOCK,同時處於 prepare 狀態的事務,在備庫執行時是可以並行的;處於 prepare 狀態的事務,與處於 commit 狀態的事務之間,在備庫執行時也是可以並行的。

4.3 MySQL 5.7.22 的並行複製

MySQL 5.7.22 版本里,MySQL 增加了一個新的並行複製策略,基於 WRITESET 的並行複製。
相應地,新增了一個引數 binlog-transaction-dependency-tracking,用來控制是否啟用這個新策略。這個引數的可選值有以下三種。

  • COMMIT_ORDER,表示的就是前面介紹的,根據同時進入 prepare 和 commit 來判斷是否可以並行的策略。
  • WRITESET,表示的是對於事務涉及更新的每一行,計算出這一行的 hash 值,組成集合 writeset。如果兩個事務沒有操作相同的行,也就是說它們的 writeset 沒有交集,就可以並行。
  • WRITESET_SESSION,是在 WRITESET 的基礎上多了一個約束,即在主庫上同一個執行緒先後執行的兩個事務,在備庫執行的時候,要保證相同的先後順序。


5 基於 GTID 的複製

透過 sql_slave_skip_counter 跳過事務和透過 slave_skip_errors 忽略錯誤的方法,雖然都最終可以建立從庫 B 和新主庫 A’的主備關係,但這兩種操作都很複雜,而且容易出錯。MySQL 5.6 版本引入了 GTID,解決了這個問題。並且 GTID 複製模式,讓我們配置主從更加簡單。




About Me

........................................................................................................................

● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除

● 本文在個人微 信公眾號( DB寶)上有同步更新

● QQ群號: 230161599 、618766405,微信群私聊

● 個人QQ號(646634621),微 訊號(db_bao),註明新增緣由

● 於 2020年11月完成

● 最新修改時間:2020年11月

● 版權所有,歡迎分享本文,轉載請保留出處

........................................................................................................................

小麥苗的微店

● 小麥苗出版的資料庫類叢書: http://blog.itpub.net/26736162/viewspace-2142121/

小麥苗OCP、OCM、高可用、DBA學習班http://blog.itpub.net/26736162/viewspace-2148098/

● 資料庫筆試面試題庫及解答: http://blog.itpub.net/26736162/viewspace-2134706/

........................................................................................................................

請掃描下面的二維碼來關注小麥苗的微 信公眾號( DB寶)及QQ群(230161599、618766405)、新增小麥苗微 信(db_bao), 學習最實用的資料庫技術。

........................................................................................................................

 

 



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2734424/,如需轉載,請註明出處,否則將追究法律責任。

相關文章