《Mysql實例MySQL數據庫復制概論》要點:
本文介紹了Mysql實例MySQL數據庫復制概論,希望對您有用。如果有疑問,可以聯系我們。
MYSQL實例WHAT?
MYSQL實例MySQL復制使得一臺Mysql數據庫服務器的數據被拷貝到其他一臺或者多臺數據庫服務器,前者通常被叫做Master,后者通常被叫做Slave.
MYSQL實例
MYSQL實例MySQL復制示意圖
MYSQL實例復制的結果是集群(Cluster)中的所有數據庫服務器得到的數據理論上都是一樣的,都是同一份數據,只是有多個copy.MySQL默認內建的復制策略是異步的,基于不同的配置,Slave不一定要一直和Master保持連接不斷的復制或等待復制,我們指定復制所有的數據庫,一部分數據庫,甚至是某個數據庫的某部分的表.
MYSQL實例MySQL復制支持多種不同的復制策略,包括同步、半同步、異步和延遲策略等.
MYSQL實例同步策略:Master要等待所有Slave應答之后才會提交(MySql對DB操作的提交通常是先對操作事件進行二進制日志文件寫入然后再進行提交).
MYSQL實例半同步策略:Master等待至少一個Slave應答就可以提交.
MYSQL實例異步策略:Master不需要等待Slave應答就可以提交.
MYSQL實例延遲策略:Slave要至少落后Master指定的時間.
MYSQL實例MySQL復制同時支持多種不同的復制模式:
MYSQL實例基于語句的復制,Statement Based Replication(SBR).
MYSQL實例基于行的復制Row Based Replication(RBR).
MYSQL實例混合復制(Mixed).
MYSQL實例WHY?
MYSQL實例這個問題其實也就是MySQL復制有什么好處,我們可以將復制的好處歸結于下面幾類:
MYSQL實例性能方面:MySQL復制是一種Scale-out方案,也即“水平擴展”,將原來的單點負載擴散到多臺Slave機器中去,從而提高總體的服務性能.在這種方式下,所有的寫操作,當然包括UPDATE操作,都要發生在Master服務器上.讀操作發生在一臺或者多臺Slave機器上.這種模型可以在一定程度上提高總體的服務性能,Master服務器專注于寫和更新操作,Slave服務器專注于讀操作,我們同時可以通過增加Slave服務器的數量來提高讀服務的性能.
MYSQL實例防腐化:由于數據被復制到了Slave,Slave可以暫停復制進程,進行數據備份,因此可以防止數據腐化.
MYSQL實例故障恢復:同時多臺Slave如果有一臺Slave掛掉之后我們還可以從其他Slave讀取,如果配置了主從切換的話,當Master掛掉之后我們還可以選擇一臺Slave作為Master繼續提供寫服務,這大大增加了應用的可靠性.
MYSQL實例數據分析:實時數據可以存儲在Master,而數據分析可以從Slave讀取,這樣不會影響Master的性能.
MYSQL實例HOW?
MYSQL實例這里我們只介紹一下MySQL的復制是如何工作的,至于配置,網上也有很多相關的介紹,讀者具體應用的時候可以再去查閱.我們拿最常用的基于二進制文件的復制來看看.
MYSQL實例
MYSQL實例MySQL復制工作示意圖
MYSQL實例MySQL的復制過程大概如下:
MYSQL實例首先,主庫在每次準備提交事務完成數據更新操作之前都會將數據更改操作記錄到二進制日志中,這些日志是以二進制的方式記錄數據更改的事件.值得一提的是二進制日志中記錄的順序實際上是事務的提交順序,而非SQL執行語句的順序.在記錄二進制日志之后,主庫會告訴存儲引擎事務可以提交了.
MYSQL實例然后,備庫會啟動一個IO線程,之所以叫做IO線程是因為這個線程專門做IO相關的工作,包括和主庫建立連接,然后在主庫上啟動一個特殊的二進制轉儲線程,這個轉儲線程會不斷的讀取二進制日志中的事件,發送給備庫的IO線程,備庫的IO線程會將事件記錄到中繼日志中.
MYSQL實例備庫會有一個叫做SQL的線程被開啟,這個線程做的事情是讀取中繼日志中的DB操作事件在備庫執行,從而實現數據更新.
MYSQL實例總的來說,在發生復制的主庫服務器和備庫服務器中,一共有三個線程在工作.
MYSQL實例上面我們已經大概了解的什么是復制?為什么要復制?如何復制?這三個問題了,接下來我們基于上面的介紹,提出一些實際應用可能會發生的問題來思考如何解決.博主自問自答的方式-.-
MYSQL實例問答環節
MYSQL實例問題一:通過復制模型雖然讀能力可以通過擴展slave機器來達到提高,而寫能力卻不能,如果寫達到瓶頸我們應該怎么做呢?
MYSQL實例答:我們首先會得出結論,這種復制模型對于寫少讀多型應用是非常有優勢的,其次,當遇到這種問題的時候我們可以對數據庫進行分庫操作,所謂分庫,就是將業務相關性比較大的表放在同一個數據庫中,例如之前數據庫有A,B,C,D四張表,A表和B表關系比較大,而C表和D表關系比較大,這樣我們把C表和D表分離出去成為一個單獨的數據庫,通過這種方式,我們可以將原有的單點寫變成雙點寫或多點些,從而降低原有主庫的寫負載.
MYSQL實例問題二:因為復制是有延遲的,肯定會發生主庫寫了,但是從庫還沒有讀到的情況,遇到這種問題怎么辦?
MYSQL實例答:MySQL支持不同的復制策略,基于不同的復制策略達到的效果也是不一樣的,如果是異步復制,MySQL不能保證從庫立馬能夠讀到主庫實時寫入的數據,這個時候我們要權衡選擇不同復制策略的利弊來進行取舍.所謂利弊,就是我們是否對從庫的讀有那么高的實時性要求,如果真的有,我們可以考慮使用同步復制策略,但是這種策略相比于異步復制策略會大大降低主庫的響應時間和性能.我們是否可以在應用的設計層面去避開這個問題?
MYSQL實例問題三:復制的不同模式有什么優缺點?我們如何選擇?
MYSQL實例答:基于語句的復制實際上是把主庫上執行的SQL在從庫上重新執行一遍,這么做的好處是實現起來簡單,當前也有缺點,比如我們SQL里面使用了NOW(),當同一條SQL在從庫中執行的時候顯然和在主庫中執行的結果是不一樣的,注入此類問題可以類推.其次問題就是這種復制必須是串行的,為了保證串行執行,就需要更多的鎖.
MYSQL實例基于行的復制的時候二進制日志中記錄的實際上是數據本身,這樣從庫可以得到正確的數據,這種方式缺點很明顯,數據必須要存儲在二進制日志文件中,這無疑增加的二進制日志文件的大小,同時增加的IO線程的負載和網絡帶寬消耗.而相比于基于語句的復制還有一個優點就是基于行的復制無需重放查詢,省去了很多性能消耗.
MYSQL實例無論哪種復制模式都不是完美的,日志如何選擇,這個問題可以在理解他們的優缺點之后進行權衡.
MYSQL實例問題四:復制的工作過程只有三個線程來完成,對于Master來說,寫是并發的,也就出現了一個IO線程要把所有并發的數據變更事件記錄,這個IO線程會不會累死?當一個Master對應多個Slave的時候,其實在Master中會喚起多個IO線程,這無疑會增加Master的資源開銷,如果出現事件堆積,也就是事件太多,來不及及時發送出去怎么辦?另外就是Slave那邊的IO線程和SQL線程也會有對應主庫并發數據變更事件,而Slave方單個線程處理的問題,這個時候Slave線程會不會累死?
MYSQL實例答:上面的問題確實會發生,上面第一個問題和第二個問題其實是寫負載的問題,當事件堆積太多,從庫時延就會變大,Slave單SQL線程問題據說有參數可以開啟并行操作,這個大家可以確認一下.
MYSQL實例問題五:針對復制工作過程可能會出現的問題,主庫寫完二進制日志文件同時都會保存二進制日志的偏移量,但是當斷電的時候,二進制日志文件沒有刷新到磁盤,主庫重新啟動之后,從庫嘗試讀該偏移量的二進制日志,會出現讀不到的情況,這個問題應該怎么解決?
MYSQL實例答:首先如果開啟了sync_binlog選項,對于innodb同時設置innodb_flush_log_at_trx_commot=1,則可以保證二進制日志文件會被寫入磁盤,但MyISAM引擎可能會導致數據損壞.如果沒有開啟這個選項,則可以通過制定從庫的二進制偏移量為下一個二進制日志文件的開頭,但是不能解決事件丟失問題.
MYSQL實例問題六:從庫在非計劃的關閉或重啟時,回去讀master.info文件去找上次停止復制的位置,這同樣會有一個問題,如果master.info不正確,就會導致復制數據不一致的情況,遇到這個問題怎么辦?
MYSQL實例答:這個問題可以通過兩種方式解決,一是控制master.info在從庫非計劃關閉或重啟的時候讓master.info能夠同步到磁盤,這樣下次啟動的時候就不會讀取錯誤的信息,這有助于減少錯誤的發生概率.另外想要找到正確的復制位置是困難的,我們也可以選擇忽略錯誤.
MYSQL實例……
MYSQL實例其實問題也是蠻多的,這里就不再繼續提問了,包括如果主庫二進制日志文件損壞怎么辦?從庫中繼日志文件損壞怎么辦?因為每個環節都不是百分之一百可靠的,因此我們必須對可能遇到的問題提出假設,思考解決方案.本文通過黃金圈法則提出的三個問題來認識MySQL復制,通過自問自答的形式來對主體的一些可能存在的應用問題進行討論,對于復制方面還存在很多的實際應用問題,這里只是拋磚引玉,還請數據庫大牛們多多指教.
來源:http://my.oschina.net/andylucc/blog/631591
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/6159.html