1. 程式人生 > >MySQL binlog資料庫同步技術總結

MySQL binlog資料庫同步技術總結

binlog是MySQL以二進位制形式列印的日誌,它預設不加密、不壓縮。每個正常的binlog檔案頭部有4個位元組的標記,值為0xfe 0x62 0x69 0x6e(magic數字標記是binlog檔案)。從第4個位元組之後是一個一個的event,log_event是binlog裡的單位,即正常情況下binlog按照逐log_event的形式增長。除去頭部的標記,binlog就是一個log_event的序列。每個log_event都獨立單元,沒有互相引用的關係,它也有自己的二進位制頭部,主要是記錄了時間戳、型別標記等描述資訊。

Binlog模式分三種Row、Statement、Mixed

Row模式儲存的是資料修改後的結果,binlog中可以不記錄執行的sql語句的上下文相關的資訊,僅僅只需要記錄那一條記錄被修改了,修改成什麼樣了。對於update mytable set col1=’abc’ where col2=’c’在row模式下可能產生大量的資料,因為語句雖然是一條,但實際影響的資料記錄卻可能很多。而對於alter table、drop table、create table等資訊在Row模式下則不會產生大量的log條目,因為它還是記錄的語句,而不是單行資料的變化情況。

Statemnet模式每一條會修改資料的sql都會記錄到 master的binlog中。slave在複製的時候sql程序會解析成和原來master端執行過的相同的sql來再次執行。由於他是記錄的執行語句,所以,為了讓這些語句在slave端也能正確執行,那麼他還必須記錄每條語句在執行的時候的一些相關資訊,也就是上下文資訊,以保證所有語句在slave端杯執行的時候能夠得到和在master端執行時候相同的結果。

Mixed模式則是前兩種的混合,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日誌形式,也就是在Statement和Row之間選擇一種。選擇性的使用面向行資料變化的Row方式記錄,主要是面對一些未決語句(nondeterministic),考慮到安全問題,避免主從庫之間資料出現不一致,比如語句面向多行插入,其中又有auto-increment的欄位,資料庫儲存引擎不同,可能帶來插入順序

mysql主從同步延遲原理

要了解MySQL資料庫主從同步延遲原理,我們先從MySQL的資料庫主從複製原理說起:

MySQL binlog資料庫同步技術總結

MySQL的主從複製都是單執行緒的操作,主庫對所有DDL和DML產生的日誌寫進binlog,由於binlog是順序寫,所以效率很高。Slave的IO Thread執行緒從主庫中binlog中讀取取日誌。Slave的SQLThread執行緒將主庫的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是隨即的,不是順序的,成本高很多。由於SQL Thread也是單執行緒的,如果slave上的其他查詢產生lock爭用,又或者一個DML語句(大事務、大查詢)執行了幾分鐘,那麼所有之後的DML會等待這個DML執行完才會繼續執行,這就導致了延時。

主從同步延遲的引發原因

    1、Master負載

    2、Slave負載

    3、網路延遲

    4、機器配置(cpu、記憶體、硬碟)

總之,當主庫的併發較高時,產生的DML數量超過slave的SQL Thread所能處理的速度,或者當slave中有大型query語句產生了鎖等待那麼延時就產生了。

同步延遲的解決方案

  • 最簡單的減少slave同步延時,儘量讓主庫的DDL快速執行。還有就是主庫是寫,對資料安全性較高,比如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設定,而slave則不需要這麼高的資料安全,完全可以講sync_binlog設定為0或者關閉binlog,innodb_flushlog也可以設定為0來提高sql的執行效率,從庫關閉binlog記錄。另外就是使用比主庫更好的硬體裝置作為slave。
  • 在業務架構上將不同的業務分佈到不同的物理資料庫上,同一個業務分庫架構,在業務層與資料庫之間增加分散式快取以便減少主庫的壓力。
  • 在mysql 5.7版本後開始支援多執行緒並行複製技術enhanced multi-threaded slave(簡稱MTS)。

MySQL並行同步機制

並行同步在MySQL5.6就開始支援,只不過在5.6時是基於schema的,也就是基於庫的,相比於5.7的機制要遜色的多。MySQL 5.7才可稱為真正的並行複製,這其中最為主要的原因就是slave伺服器的回放與主機是一致的。即master伺服器上是怎麼並行執行的slave上就怎樣進行並行回放。不再有庫的並行複製限制。

從MySQL官方來看,其並行複製的原本計劃是支援表級的並行複製和行級的並行複製,行級的並行複製通過解析ROW格式的二進位制日誌的方式來完成。但是最終出現給小夥伴的確是在開發計劃中稱為:MTS: Prepared transactions slave parallel applier。該並行複製的思想最早是由MariaDB的Kristain提出,並已在MariaDB 10中出現,相信很多選擇MariaDB的小夥伴最為看重的功能之一就是並行複製。

MySQL 5.7並行複製的思想簡單易懂,一言以蔽之:一個組提交的事務都是可以並行回放,因為這些事務都已進入到事務的prepare階段,則說明事務之間沒有任何衝突(否則就不可能提交)。為了相容MySQL 5.6基於庫的並行複製,5.7引入了新的變數slave-parallel-type,其可以配置的值有:

• DATABASE:預設值,基於庫的並行複製方式

• LOGICAL_CLOCK:基於組提交的並行複製方式

MySQL在binlog中定義了兩個Logical_clock的變數:

• max_c ommitted_transaction:記錄上次組提交時的logical_clock,代表上述mysqlbinlog中的last_committed

• transaction_counter:記錄當前組提交中各事務的logcial_clock,代表上述mysqlbinlog中的sequence_number

通過工具檢查binlog檔案,可以發現較之原來的二進位制日誌內容多了last_committed和sequence_number,last_committed表示事務提交的時候,上次事務提交的編號,如果事務具有相同的last_committed,表示這些事務都在一組內,可以進行並行的回放。例如上述last_committed為0的事務有6個,表示組提交時提交了6個事務,而這6個事務在從機是可以進行並行回放的。

提升同步的策略中,有很多實現,包括MySQL各版本的實現及MariaDB等分支的實現上,按按粒度區分的三個策略,粒度從粗到細是按庫、按表、按行,而MySQL5.7按照commit_id的策略適用範圍更廣,改進策略併發性更優。