MySQL加強(Loss-less)半同步複製

原文地址:my-replication-life.blogspot.com/2013/09/los…
譯者:沈剛html

前言

許多用戶在他們的數據庫環境中使用半同步複製架構以提升數據的完整性。今天我要向你們介紹一下MySQL在5.7版本中針對半同步複製增長的新特性,這個新特性進一步加強了主庫和備庫之間的數據完整性。git

在存儲引擎層提交以前等待從庫ACK

正如你所知的,在半同步複製架構中,主庫上的事務提交以前會等待一個從庫返回ACK信號。爲了進一步增長數據的完整性,新的特性將等待從庫返回ACK信號的時間點提早了(相對於MySQL5.5以及MySQL5.6),新特性中主庫上的事務會在存儲引擎層提交以前一直等待從庫返回ACK信號。 github

有了這個新特性以後,半同步複製能夠保證:數據庫

  • 在主庫crash的狀況下,全部在主庫上已經提交的事務已經被複制到至少一個從庫上

顯而易見,由於主庫上的事務沒法提交,除非從庫返回了ACK信號(或者超時)。 這對於用戶來講有兩個有利點:架構

  • 強數據完整性,並解決了幻讀的問題
  • 簡化主庫Crash Recovery的過程

強數據完整性解決幻讀問題

在MySQL 5.5以及MySQL 5.6開啓半同步複製的場景下,主庫上的事務在存儲引擎層提交以後,須要等待從庫返回ACK信號。而且在接收到從庫返回ACK信號或者等待超時纔會返回給客戶端一個提交結果。 less

存儲引擎層的提交,會持久化記錄而且釋放這些記錄上的鎖。因此在存儲引擎層提交以後,其他的會話能夠操做並讀取這些記錄,即便這個會話還在等待從庫返回ACK信號。這樣在主庫crash,從庫接管主庫的狀況下,產生幻讀的現象。 ide

在這個新特性中,不會發生幻讀。User2在第一次SELECT的時候不會獲取3這個值,由於3這條記錄尚未複製從庫,因此並無在存儲引擎層提交。性能

簡化主庫Crash Recovery的過程

在MySQL 5.7.2以前的版本中,用戶在恢復crash掉的主庫的時候,須要作如下操做:優化

  • 手動清除並無被複制到從庫上的binlog事務
  • 手動回滾已經提交可是尚未被複制的事務

由於新的特性保證全部的事務在提交以前都至少複製到一個從庫上了,因此第二步能夠不用作了。ui

如何設置新特性

這個特性的設置很簡單,用戶無需任何設置,由於在MySQL 5.7.2版本以後該特性是默認開啓的。用戶能夠設置rpl_semi_sync_master_wait_point變量控制主庫等待從庫返回ACK信號的時間點。

這是一個全局、可動態修改的參數。在5.7.2版本以後,該變量的默認值是AFTER_SYNC,該值表示,主庫上的事務會在flush binlog以後,在存儲引擎層提交以前的時間點,等待從庫返回ACK信號。

你也能夠將該參數設置爲AFTER_COMMIT值不開啓新特性,保持和以前版本同樣的機制。可是我想不到一個理由讓用戶設置該變量爲AFTER_COMMIT值。開啓新特性並無反作用,也不會對數據庫性能產生影響。

Dump線程的優化

在開發這個特性的過程當中,咱們對Dump線程作了一些優化。咱們重構了Dump線程先關的代碼,可是更重要的是,在Dump線程讀取binlog event的時候,Dump線程不會再去獲取binlog鎖。這一改進增長了主庫的一個吞吐量而且減少了主從之間的延遲。

最後

總而言之,這個新特性保證了主庫和從庫之間的數據完整性、一致性,並不會帶來任何反作用以及性能印象。我強烈推薦你去嘗試該特性。

A special thanks to Mr. Zhenxing Zhou a community user who contributed a patch implementing a similar idea based on MySQL 5.5. Even though we did not take his patch (the 5.7 codebase changed quite a lot compared to 5.5), his feature request was yet another source of motivation and inspiration.

博客地址:win-man.github.io/
公衆號:歡迎關注

相關文章
相關標籤/搜索