mysql 5.7变化_从MySQL 5.5到5.7看复制的演进
概要:MySQL 5.5 支持單線程模式復(fù)制,MySQL 5.6 支持庫級別的并行復(fù)制,MySQL 5.7 支持事務(wù)級別并行復(fù)制。結(jié)合這個主線我們可以來分析一下MySQL以及社區(qū)發(fā)展的一個前因后果。
MySQL5.5,對于復(fù)制我們可以這樣理解:主庫有個 dump binlog thread 不停的 dump binlog,然后以event為單位發(fā)送給從庫 的 iothread,iothread 收到主庫傳過來的event寫入relaylog ,隨后sql_thread 讀取relaylog 對這些event以事務(wù)為單位進(jìn)行回放。
那么對于MySQL 5.5這個版本,在我們的使用過程中遇到那些問題,或者有那些不便呢?
首先DB壓力偏大時,從庫帶來的延遲較大,影響只讀業(yè)務(wù)
由于新硬件的發(fā)展,SSD的引入和多core的CPU,master節(jié)點的并發(fā)處理能力持續(xù)提升,slave節(jié)點完全按照binlog寫入順序的單線程回放,已完全跟不上master節(jié)點的吞吐能力。
在不考慮主從硬件配置差異情況下,延遲大的其根本原因在于:Master壓力過大,而Slave是單線程回放日志。那么要解決這個問題,從技術(shù)上來說可以把單線程變?yōu)槎嗑€程,利用并行帶來的優(yōu)勢;從業(yè)務(wù)上來說可以進(jìn)行拆庫,把一些業(yè)務(wù)線或者功能模塊獨(dú)立出去;更進(jìn)一步我們可以拆表,把壓力分擔(dān)到多個Master上去。
假如我們在不變動業(yè)務(wù)的情況下,從技術(shù)面來解決這個問題有哪些方向呢:
社區(qū)的解決方案:阿里開源的canal,基于表級別并行同步,可以減小同步延遲時間
官方的解決方案:在2011年10月份發(fā)布了一個里程碑版本基于schema級別的并行復(fù)制[MySQL5.6.3 (multi-threaded slave)],以及基于group Commit的 MySQL5.7版本,最大化還原主庫并行度。
MySQL5.6,對于復(fù)制我們可以這樣理解,主庫有個 dump binlog thread 不停的 dump binlog,然后以event為單位發(fā)送給從庫 的 iothread,iothread 收到主庫傳過來的event寫入relaylog。【隨后的事情和MySQL5.5就發(fā)生了一些變化】,由coordinator線程來讀取relaylog,然后根據(jù)不同的db以事務(wù)為單位分配到不同的work線程。如果binlog row event操作的是不同的schema的對象,在確定沒有DDL和foreign key依賴的情況下,就可以實現(xiàn)并行復(fù)制。
MySQL5.7可以說是最大還原了主庫上的并行,在基于Group Commit的基礎(chǔ)上,所有在主庫上能夠完成prepared的語句表示沒有數(shù)據(jù)沖突,分配成相同的lastcommitted,就可以在slave節(jié)點并行復(fù)制。 那么它是如何識別那些事務(wù)是一起提交的呢?其實就是在gtid event 中增加了兩個字段【int64 lastcommitted;int64 sequencenumber】,當(dāng)slave的coordinator線程在分發(fā)這些event的時候,具有相同lastcommitted 的事務(wù)(event的集合)就可以同時發(fā)送給不同的work線程,達(dá)到并行同步的目的。
小結(jié):就并行復(fù)制,按粒度區(qū)分有三種策略,粒度從粗到細(xì)是按庫、按表、按行。 這三個的對比中,并行度越來越大,額外損耗也是。無關(guān)大事務(wù)不會影響并發(fā)度。按照commit_id 的策略,適用范圍更廣,額外消耗也低。5.7的改進(jìn)策略并發(fā)性更優(yōu)。但出現(xiàn)大事務(wù)會拖后腿。
那么我們只有一實例只有一個database,這種情況下我們就只有拆庫拆表了:
對于這種情況下,我們可以選擇在應(yīng)用層做分庫分表,也可以選擇搞個中間層。不同的方案有不同的優(yōu)劣。
應(yīng)用層具有較好的性能,但是代碼耦合在業(yè)務(wù),如果后續(xù)擴(kuò)容還需該代碼,不能做到平滑擴(kuò)容拆分,假如有多個業(yè)務(wù)都需要實現(xiàn)同樣的功能,那么會帶來重復(fù)的工作量,而且工作難度也上升一個臺階。
中間件層具有較好的擴(kuò)展性,低耦合性,如果DB擴(kuò)容拆分,應(yīng)用可以做到無感知,無改動。那么也有一些成熟的開源方案,比如MyCAT,Cobar,Atlas,kingshard等。
其次主從切換時帶來的復(fù)雜度較大,需要計算position或者重做從庫
一般情況下我們的MySQL都是一主多從架構(gòu),這樣既能給我們提供讀寫分離、負(fù)載均衡的便利,也能給我們提供容災(zāi)的能力。但是假如我們的主庫掛掉,這時我們會把從庫提升為主庫,但是在把從庫提升為新主的時候帶來了架構(gòu)的微變化。為了還能利用以上便利、提供容災(zāi)能力我們還得重新構(gòu)建這個新主的多個從庫。此時問題就來了,我們從庫必須知道我當(dāng)前應(yīng)該從Master 的那個位置開始復(fù)制,也就是說必須拿到Master的position 。為了拿到這個位置我們有兩種辦法,一種簡單粗暴,重做Slave;另一種是通過一些列復(fù)雜計算、補(bǔ)回差異數(shù)據(jù),算出當(dāng)前數(shù)據(jù)和新主數(shù)據(jù)的差異點,從而得到新主庫position,導(dǎo)致HA切換和數(shù)據(jù)保護(hù)帶來巨大的挑戰(zhàn)。
MMM架構(gòu)(Master-Master replication manager for MySQL)
MMM是一套支持雙主故障切換和雙主日常管理的腳本程序,可以再主庫故障時保證熱備切換為新主庫,并且自動的將從庫指向新主。但是這個架構(gòu)本身不能保證數(shù)據(jù)的一致性。
MHA架構(gòu)(Master High Availability)
MHA目前在MySQL高可用方面是一個相對成熟的解決方案,在自動進(jìn)行故障切換的過程中,能最大程度上保證數(shù)據(jù)的一致性,以達(dá)到真正意義上的高可用。
那么HMA是如何最大程度保證數(shù)據(jù)一致的呢?當(dāng)主庫down掉時,MHA試圖從宕機(jī)的主服務(wù)器上保存二進(jìn)制日志,最大程度的保證數(shù)據(jù)的不丟失,但這并不總是可行的。如果主庫發(fā)送down機(jī),日志會出現(xiàn)不同程度的丟失,有個解決辦法就是設(shè)置半同步復(fù)制。MHA在把從提升為主的過程中,會進(jìn)行一系列日志對比,找到最接近主庫的從庫提升為新主庫,把從庫間差異化的數(shù)據(jù)拿出來進(jìn)行應(yīng)用等等。
GTID?(Global Transaction ID)
在MySQL 5.6 以后官方引入了GTID,即在整個集群內(nèi)部,每個事務(wù)都有全局唯一的一個標(biāo)識,這樣一來,當(dāng)我們主庫發(fā)送down掉,或者M(jìn)ySQL架構(gòu)有調(diào)整的時候,我們就不用很頭疼的去計算position;或者去配置略為復(fù)雜的MHA。我們只需要輕輕松松敲個CHANGE MASTER 命令帶上AUTO_POSITION就可以了,然后關(guān)于MASTER該從哪個binlog開始推送event給Slave這個完全由MySQL來幫我們計算。這個真是DBA們的福音啊。
簡單看看,為什么這么GTID這么神奇吧。在MySQL內(nèi)部幫我們記錄著 gtidpurged 和gtidexecuted 兩個集合。顧名思義,gtidexecuted 代表的時當(dāng)前已經(jīng)執(zhí)行過的GTID的集合;一般情況下我們binlog不可能永久保存,那么gtidpurged代表的就是當(dāng)前binlog已經(jīng)沒有的GTID集合,它是gtidexecuted的子集。我們知道在事務(wù)是不能跨binlog存在的,意味著每個binlog都會有一個完整的事務(wù)集合,同樣每個binlog文件的 header 部分,也都存放著這個binlog以前的 gtidexecuted 集合。我們的Slave 在應(yīng)用Binlog的時候都會記錄自己當(dāng)前已經(jīng)執(zhí)行過的最后一個事務(wù)GTID,那么我們在切換主庫的時候,Slave就會把這個ID給帶上,然后Master端就會拿到這個GTID和自己當(dāng)前的gtidexecuted、gtidpurged 集合進(jìn)行對比,從而給到Slave一個合理的解釋。
OK,到這里MySQL從5.5的單線程復(fù)制,到5.6基于Schema級別的復(fù)制,再到5.7最大化還原主庫的并行就接近尾聲了。同時在這期間我們還給出了一些社區(qū)上、或者非技術(shù)上的解決方案。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的mysql 5.7变化_从MySQL 5.5到5.7看复制的演进的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wxpython 按钮跳notebook
- 下一篇: 怎样查询个人养老金账户余额 养老金账户余