1. 程式人生 > >談談MySQL的WriteSet並行復制

談談MySQL的WriteSet並行復制

場景 自我 做了 問題 包含 enc tran hash spa

歷史背景

  歲月更叠中我已經從事MySQL-DBA這個工作三個年頭,見證MySQL從“基本可用”,“邊緣系統可以用MySQL”,“哦操!你怎麽不用MySQL”;

  正所謂!“一個數據庫的境遇既取決於歷史的進程,取決於它的自我奮鬥!”,關於“歷史的進程”在此不表,關於“自我奮鬥”這裏也只想談一下

  並行復制的幾個關鍵時間結點

  總的來說MySQL關於並行復制到目前為止經歷過三個比較關鍵的時間結點“庫間並發”,“組提交”,“寫集合”;真可謂是江山代有人才出,前

  浪死在沙灘上;總的來說就後面的比前面的不知道高到哪裏去了!

庫間並發

  庫間並發的理論依據是這樣的 ---- 一個實例內可能會有多個庫(schema),不同的庫之間沒有什麽依賴關系,所以在slave那邊為

  每一個庫(schema)單獨起一個SQL線程,這樣就能通過多線程並行復制的方式來提高主從復制的效率。

  這個理論聽起來沒問題,但是事實上一個實例也就一個業務庫,所以這種庫間並發就沒什麽作用了;也就是說這個方式的適用場景

  比較少,針對這個不足直到“組提交”才解決!

組提交

  組提交的理論依據是這樣的 --- 如果多個事務他們能在同一時間內提交,這個就間接說明了這個幾個事務鎖上是沒有沖突的,

  也是就說他們各自持有不同的鎖,互不影響;邏輯上我們幾個事務看一個組,在slave以“組”為單位分配給SQL線程執行,這樣

  多個SQL線程就可以並行跑了;而且不在以庫為並行的粒度,效果上要比“庫間並發”要好一些。

  這個事實上也有一些問題,因為它要求庫上要有一定的並發度,不然就有可能變成每個組裏面只有一個事務,這樣就有串行沒什麽

  區別了,為了解決這個問題MySQL提供了兩個參數就是希望在提交時先等一等,盡可能的讓組內多一些事務,以提高並行復制的效率。

  “binlog_group_commit_sync_no_delay_count” 設置一個下水位,也就是說一個組要湊足多少個事務再提交;為子防止永遠也湊不足

  那麽多個事務MySQL還以時間為維度給出了另一個參數“binlog_group_commit_sync_delay”這個參數就是最多等多久,

  超過這個時間長度後就算沒有湊足也提交。

  

  親身經歷呀! 這兩個參數特別難找到合的值,就算今天合適,過幾天業務上有點變化後,又可能變的不合適了;如果MySQL能自己

  達到一個自適應的效果就好了;這個自適用要到WriteSet才完成(WriteSet並不是通過自動調整這兩個參數來完成,

  它采用了完全不同的解決思路)。

WriteSet

  WriteSet解決了什麽問題?當然是解決了“組提交”的問題啦! 說了和沒說一個樣,好下面我們來舉個例子(比較學院派);假設你第一天

  更新了id == 1 的那一行,第二天你更新了id == 2 的那一行,第三天有個slave過來同步你的數據啦! 以“組提交”的尿性,這兩個更新

  會被打包到不同的“組”,也就是說會有兩個組;由於每個組內只有一個事務,所以邏輯上就串行了,起來!

  身為DBA的你一可以看出來這兩個事實上是可以打包到同一個組裏來的,因為他們互不沖突,就算打包到同一個組也不引起數據的不

  一致。 於是你有兩個辦法

  辦法1): 妹妹你大膽的把“binlog_group_commit_sync_no_delay_count”設置成 2,也就是說一個組至少要包含兩個事務,並且把

  “binlog_group_commit_sync_delay”設置成24小時以上!如果你真的做了,你就可以回家了,你的數據庫太慢了(第一條update等了一天),

  才完成!

  辦法2): 叫MySQL用一本小本子記下它最近改了什麽,如果現在要改的數據和之前的數據不沖突,那麽他們就可以把包到同一個組;還是

  我們剛才的例子,由於第二天改的值的id==2所以它和第一天的不沖突,那麽它完全可以把第二天的更新和第一天的更新打包到同一個組。

  這樣組裏面就有兩個事務了,在slave第三天回放時就會有一種並行的效果。

  這本小本子這麽牛逼可以做大一點嗎?當然!binlog_transaction_dependency_history_size 這個參數就小本子的容量了;那我的MySQL

  有這本小本子嗎? 如果你的mysql比mysql-5.7.22新的話,小本子就是它生來就有的。

  也就是說“WriteSet”是站在“組提交”這個巨人的基礎之間建立起來的,而且是在master上做的自“適應”打包分組,所以你只要在master上

  新增兩個參數

binlog_transaction_dependency_tracking  = WRITESET                 #    COMMIT_ORDER          
transaction_write_set_extraction        = XXHASH64

  理論說完了,下面我們看一下實踐。

  

  

  

  

----

談談MySQL的WriteSet並行復制