最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

防止服務(wù)器宕機(jī)時(shí)MySQL數(shù)據(jù)丟失的幾種方案

 更新時(shí)間:2015年06月05日 09:17:45   作者:siddontang  
這篇文章主要介紹了防止服務(wù)器宕機(jī)時(shí)MySQL數(shù)據(jù)丟失的幾種方案,結(jié)合實(shí)踐介紹了Replication和Monitor以及Failover這三個(gè)項(xiàng)目的應(yīng)用,需要的朋友可以參考下

對(duì)于多數(shù)應(yīng)用來(lái)說(shuō),MySQL都是作為最關(guān)鍵的數(shù)據(jù)存儲(chǔ)中心的,所以,如何讓MySQL提供HA服務(wù),是我們不得不面對(duì)的一個(gè)問(wèn)題。當(dāng)master當(dāng)機(jī)的時(shí)候,我們?nèi)绾伪WC數(shù)據(jù)盡可能的不丟失,如何保證快速的獲知master當(dāng)機(jī)并進(jìn)行相應(yīng)的故障轉(zhuǎn)移處理,都是需要我們好好思考的。這里,筆者將結(jié)合這段時(shí)間做的MySQL proxy以及toolsets相關(guān)工作,說(shuō)說(shuō)我們現(xiàn)階段以及后續(xù)會(huì)在項(xiàng)目中采用的MySQL HA方案。
Replication
要保證MySQL數(shù)據(jù)不丟失,replication是一個(gè)很好的解決方案,而MySQL也提供了一套強(qiáng)大的replication機(jī)制。只是我們需要知道,為了性能考量,replication是采用的asynchronous模式,也就是寫(xiě)入的數(shù)據(jù)并不會(huì)同步更新到slave上面,如果這時(shí)候master當(dāng)機(jī),我們?nèi)匀豢赡軙?huì)面臨數(shù)據(jù)丟失的風(fēng)險(xiǎn)。

為了解決這個(gè)問(wèn)題,我們可以使用semi-synchronous replication,semi-synchronous replication的原理很簡(jiǎn)單,當(dāng)master處理完一個(gè)事務(wù),它會(huì)等待至少一個(gè)支持semi-synchronous的slave確認(rèn)收到了該事件并將其寫(xiě)入relay-log之后,才會(huì)返回。這樣即使master當(dāng)機(jī),最少也有一個(gè)slave獲取到了完整的數(shù)據(jù)。

但是,semi-synchronous并不是100%的保證數(shù)據(jù)不會(huì)丟失,如果master在完成事務(wù)并將其發(fā)送給slave的時(shí)候崩潰,仍然可能造成數(shù)據(jù)丟失。只是相比于傳統(tǒng)的異步復(fù)制,semi-synchronous replication能極大地提升數(shù)據(jù)安全。更為重要的是,它并不慢,MHA的作者都說(shuō)他們?cè)趂acebook的生產(chǎn)環(huán)境中使用了semi-synchronous(這里),所以我覺(jué)得真心沒(méi)必要擔(dān)心它的性能問(wèn)題,除非你的業(yè)務(wù)量級(jí)已經(jīng)完全超越了facebook或者google。在這篇文章里面已經(jīng)提到,MySQL 5.7之后已經(jīng)使用了Loss-Less Semi-Synchronous replication,所以丟數(shù)據(jù)的概率已經(jīng)很小了。

如果真的想完全保證數(shù)據(jù)不會(huì)丟失,現(xiàn)階段一個(gè)比較好的辦法就是使用gelera,一個(gè)MySQL集群解決方案,它通過(guò)同時(shí)寫(xiě)三份的策略來(lái)保證數(shù)據(jù)不會(huì)丟失。筆者沒(méi)有任何使用gelera的經(jīng)驗(yàn),只是知道業(yè)界已經(jīng)有公司將其用于生產(chǎn)環(huán)境中,性能應(yīng)該也不是問(wèn)題。但gelera對(duì)MySQL代碼侵入性較強(qiáng),可能對(duì)某些有代碼潔癖的同學(xué)來(lái)說(shuō)不合適了:-)

我們還可以使用drbd來(lái)實(shí)現(xiàn)MySQL數(shù)據(jù)復(fù)制,MySQL官方文檔有一篇文檔有詳細(xì)介紹,但筆者并未采用這套方案,MHA的作者寫(xiě)了一些采用drdb的問(wèn)題,在這里,僅供參考。

在后續(xù)的項(xiàng)目中,筆者會(huì)優(yōu)先使用semi-synchronous replication的解決方案,如果數(shù)據(jù)真的非常重要,則會(huì)考慮使用gelera。
Monitor

前面我們說(shuō)了使用replication機(jī)制來(lái)保證master當(dāng)機(jī)之后盡可能的數(shù)據(jù)不丟失,但是我們不能等到master當(dāng)了幾分鐘才知道出現(xiàn)問(wèn)題了。所以一套好的監(jiān)控工具是必不可少的。

當(dāng)master當(dāng)?shù)糁?,monitor能快速的檢測(cè)到并做后續(xù)處理,譬如郵件通知管理員,或者通知守護(hù)程序快速進(jìn)行failover。

通常,對(duì)于一個(gè)服務(wù)的監(jiān)控,我們采用keepalived或者h(yuǎn)eartbeat的方式,這樣當(dāng)master當(dāng)機(jī)之后,我們能很方便的切換到備機(jī)上面。但他們?nèi)匀徊荒芎芗磿r(shí)的檢測(cè)到服務(wù)不可用。筆者的公司現(xiàn)階段使用的是keepalived的方式,但后續(xù)筆者更傾向于使用zookeeper來(lái)解決整個(gè)MySQL集群的monitor以及failover。

對(duì)于任何一個(gè)MySQL實(shí)例,我們都有一個(gè)對(duì)應(yīng)的agent程序,agent跟該MySQL實(shí)例放到同一臺(tái)機(jī)器上面,并且定時(shí)的對(duì)MySQL實(shí)例發(fā)送ping命令檢測(cè)其可用性,同時(shí)該agent通過(guò)ephemeral的方式掛載到zookeeper上面。這樣,我們可以就能知道MySQL是否當(dāng)機(jī),主要有以下幾種情況:

  •     機(jī)器當(dāng)機(jī),這樣MySQL以及agent都會(huì)當(dāng)?shù)?,agent與zookeeper連接自然斷開(kāi)
  •     MySQL當(dāng)?shù)簦琣gent發(fā)現(xiàn)ping不通,主動(dòng)斷開(kāi)與zookeeper的連接
  •     Agent當(dāng)?shù)?,但MySQL未當(dāng)

上面三種情況,我們都可以認(rèn)為MySQL機(jī)器出現(xiàn)了問(wèn)題,并且zookeeper能夠立即感知。agent與zookeeper斷開(kāi)了連接,zookeeper觸發(fā)相應(yīng)的children changed事件,監(jiān)控到該事件的管控服務(wù)就可以做相應(yīng)的處理。譬如如果是上面前兩種情況,管控服務(wù)就能自動(dòng)進(jìn)行failover,但如果是第三種,則可能不做處理,等待機(jī)器上面crontab或者supersivord等相關(guān)服務(wù)自動(dòng)重啟agent。

使用zookeeper的好處在于它能很方便的對(duì)整個(gè)集群進(jìn)行監(jiān)控,并能即時(shí)的獲取整個(gè)集群的變化信息并觸發(fā)相應(yīng)的事件通知感興趣的服務(wù),同時(shí)協(xié)調(diào)多個(gè)服務(wù)進(jìn)行相關(guān)處理。而這些是keepalived或者h(yuǎn)eartbeat做不到或者做起來(lái)太麻煩的。

使用zookeeper的問(wèn)題在于部署起來(lái)較為復(fù)雜,同時(shí)如果進(jìn)行了failover,如何讓?xiě)?yīng)用程序獲取到最新的數(shù)據(jù)庫(kù)地址也是一個(gè)比較麻煩的問(wèn)題。

對(duì)于部署問(wèn)題,我們要保證一個(gè)MySQL搭配一個(gè)agent,幸好這年頭有了docker,所以真心很簡(jiǎn)單。而對(duì)于第二個(gè)數(shù)據(jù)庫(kù)地址更改的問(wèn)題,其實(shí)并不是使用了zookeeper才會(huì)有的,我們可以通知應(yīng)用動(dòng)態(tài)更新配置信息,VIP,或者使用proxy來(lái)解決。

雖然zookeeper的好處很多,但如果你的業(yè)務(wù)不復(fù)雜,譬如只有一個(gè)master,一個(gè)slave,zookeeper可能并不是最好的選擇,沒(méi)準(zhǔn)keepalived就夠了。
Failover

通過(guò)monitor,我們可以很方便的進(jìn)行MySQL監(jiān)控,同時(shí)在MySQL當(dāng)機(jī)之后通知相應(yīng)的服務(wù)做failover處理,假設(shè)現(xiàn)在有這樣的一個(gè)MySQL集群,a為master,b,c為其slave,當(dāng)a當(dāng)?shù)糁?,我們需要做failover,那么我們選擇b,c中的哪一個(gè)作為新的master呢?

原則很簡(jiǎn)單,哪一個(gè)slave擁有最近最多的原master數(shù)據(jù),就選哪一個(gè)作為新的master。我們可以通過(guò)show slave status這個(gè)命令來(lái)獲知哪一個(gè)slave擁有最新的數(shù)據(jù)。我們只需要比較兩個(gè)關(guān)鍵字段Master_Log_File以及Read_Master_Log_Pos,這兩個(gè)值代表了slave讀取到master哪一個(gè)binlog文件的哪一個(gè)位置,binlog的索引值越大,同時(shí)pos越大,則那一個(gè)slave就是能被提升為master。這里我們不討論多個(gè)slave可能會(huì)被提升為master的情況。

在前面的例子中,假設(shè)b被提升為master了,我們需要將c重新指向新的master b來(lái)開(kāi)始復(fù)制。我們通過(guò)CHANGE MASTER TO來(lái)重新設(shè)置c的master,但是我們?cè)趺粗酪獜腷的binlog的哪一個(gè)文件,哪一個(gè)position開(kāi)始復(fù)制呢?

GTID

為了解決這一個(gè)問(wèn)題,MySQL 5.6之后引入了GTID的概念,即uuid:gid,uuid為MySQL server的uuid,是全局唯一的,而gid則是一個(gè)遞增的事務(wù)id,通過(guò)這兩個(gè)東西,我們就能唯一標(biāo)示一個(gè)記錄到binlog中的事務(wù)。使用GTID,我們就能非常方便的進(jìn)行failover的處理。

仍然是前面的例子,假設(shè)b此時(shí)讀取到的a最后一個(gè)GTID為3E11FA47-71CA-11E1-9E33-C80AA9429562:23,而c的為3E11FA47-71CA-11E1-9E33-C80AA9429562:15,當(dāng)c指向新的master b的時(shí)候,我們通過(guò)GTID就可以知道,只要在b中的binlog中找到GTID為3E11FA47-71CA-11E1-9E33-C80AA9429562:15這個(gè)event,那么c就可以從它的下一個(gè)event的位置開(kāi)始復(fù)制了。雖然查找binlog的方式仍然是順序查找,稍顯低效暴力,但比起我們自己去猜測(cè)哪一個(gè)filename和position,要方便太多了。

google很早也有了一個(gè)Global Transaction ID的補(bǔ)丁,不過(guò)只是使用的一個(gè)遞增的整形,LedisDB就借鑒了它的思路來(lái)實(shí)現(xiàn)failover,只不過(guò)google貌似現(xiàn)在也開(kāi)始逐步遷移到MariaDB上面去了。

MariaDB的GTID實(shí)現(xiàn)跟MySQL 5.6是不一樣的,這點(diǎn)其實(shí)比較麻煩,對(duì)于我的MySQL工具集go-mysql來(lái)說(shuō),意味著要寫(xiě)兩套不同的代碼來(lái)處理GTID的情況了。后續(xù)是否支持MariaDB再看情況吧。

Pseudo GTID

GTID雖然是一個(gè)好東西,但是僅限于MySQL 5.6+,當(dāng)前仍然有大部分的業(yè)務(wù)使用的是5.6之前的版本,筆者的公司就是5.5的,而這些數(shù)據(jù)庫(kù)至少長(zhǎng)時(shí)間也不會(huì)升級(jí)到5.6的。所以我們?nèi)匀恍枰惶缀玫臋C(jī)制來(lái)選擇master binlog的filename以及position。

最初,筆者打算研究MHA的實(shí)現(xiàn),它采用的是首先復(fù)制relay log來(lái)補(bǔ)足缺失的event的方式,但筆者不怎么信任relay log,同時(shí)加之MHA采用的是perl,一個(gè)讓我完全看不懂的語(yǔ)言,所以放棄了繼續(xù)研究。

幸運(yùn)的是,筆者遇到了orchestrator這個(gè)項(xiàng)目,這真的是一個(gè)非常神奇的項(xiàng)目,它采用了一種Pseudo GTID的方式,核心代碼就是這個(gè)

   

復(fù)制代碼 代碼如下:
create database if not exists meta;
    drop event if exists meta.create_pseudo_gtid_view_event;
    delimiter ;;
    create event if not exists
      meta.create_pseudo_gtid_view_event
      on schedule every 10 second starts current_timestamp
      on completion preserve
      enable
      do
        begin
          set @pseudo_gtid := uuid();
          set @_create_statement := concat('create or replace view meta.pseudo_gtid_view as select \'', @pseudo_gtid, '\' as pseudo_gtid_unique_val from dual');
          PREPARE st FROM @_create_statement;
          EXECUTE st;
          DEALLOCATE PREPARE st;
        end
    ;;
    delimiter ;
    set global event_scheduler := 1;

它在MySQL上面創(chuàng)建了一個(gè)事件,每隔10s,就將一個(gè)uuid寫(xiě)入到一個(gè)view里面,而這個(gè)是會(huì)記錄到binlog中的,雖然我們?nèi)匀徊荒芟馟TID那樣直接定位到一個(gè)event,但也能定位到一個(gè)10s的區(qū)間了,這樣我們就能在很小的一個(gè)區(qū)間里面對(duì)比兩個(gè)MySQL的binlog了。

繼續(xù)上面的例子,假設(shè)c最后一次出現(xiàn)uuid的位置為s1,我們?cè)赽里面找到該uuid,位置為s2,然后依次對(duì)比后續(xù)的event,如果不一致,則可能出現(xiàn)了問(wèn)題,停止復(fù)制。當(dāng)遍歷到c最后一個(gè)binlog event之后,我們就能得到此時(shí)b下一個(gè)event對(duì)應(yīng)的filename以及position了,然后讓c指向這個(gè)位置開(kāi)始復(fù)制。

使用Pseudo GTID需要slave打開(kāi)log-slave-update的選項(xiàng),考慮到GTID也必須打開(kāi)該選項(xiàng),所以個(gè)人感覺(jué)完全可以接受。

后續(xù),筆者自己實(shí)現(xiàn)的failover工具,將會(huì)采用這種Pseudo GTID的方式實(shí)現(xiàn)。

在《MySQL High Availability》這本書(shū)中,作者使用了另一種GTID的做法,每次commit的時(shí)候,需要在一個(gè)表里面記錄gtid,然后就通過(guò)這個(gè)gtid來(lái)找到對(duì)應(yīng)的位置信息,只是這種方式需要業(yè)務(wù)MySQL客戶端的支持,筆者不很喜歡,就不采用了。
后記

MySQL HA一直是一個(gè)水比較深的領(lǐng)域,筆者僅僅列出了一些最近研究的東西,有些相關(guān)工具會(huì)盡量在go-mysql中實(shí)現(xiàn)。
更新

經(jīng)過(guò)一段時(shí)間的思考與研究,筆者又有了很多心得與收獲,設(shè)計(jì)的MySQL HA跟先前有了很多不一樣的地方。后來(lái)發(fā)現(xiàn),自己設(shè)計(jì)的這套HA方案,跟facebook這篇文章幾乎一樣,加之最近跟facebook的人聊天聽(tīng)到他們也正在大力實(shí)施,所以感覺(jué)自己方向是對(duì)了。

新的HA,我會(huì)完全擁抱GTID,比較這玩意的出現(xiàn)就是為了解決原先replication那一堆問(wèn)題的,所以我不會(huì)考慮非GTID的低版本MySQL了。幸運(yùn)的是,我們項(xiàng)目已經(jīng)將MySQL全部升級(jí)到5.6,完全支持GTID了。

不同于fb那篇文章將mysqlbinlog改造支持semi-sync replication協(xié)議,我是將go-mysql的replication庫(kù)支持semi-sync replication協(xié)議,這樣就能實(shí)時(shí)的將MySQL的binlog同步到一臺(tái)機(jī)器上面。這可能就是我和fb方案的唯一區(qū)別了。

只同步binlog速度鐵定比原生slave要快,畢竟少了執(zhí)行binlog里面event的過(guò)程了,而另外真正的slaves,我們?nèi)匀皇褂米钤嫉耐椒绞剑皇褂胹emi-sync replication。然后我們通過(guò)MHA監(jiān)控整個(gè)集群以及進(jìn)行故障轉(zhuǎn)移處理。

以前我總認(rèn)為MHA不好理解,但其實(shí)這是一個(gè)非常強(qiáng)大的工具,而且真正看perl,發(fā)現(xiàn)也還是看的懂得。MHA已經(jīng)被很多公司用于生產(chǎn)環(huán)境,經(jīng)受了檢驗(yàn),直接使用絕對(duì)比自己寫(xiě)一個(gè)要?jiǎng)澦?。所以后續(xù)我也不會(huì)考慮zookeeper,考慮自己寫(xiě)agent了。

相關(guān)文章

  • MySQL中出現(xiàn)亂碼和表格不對(duì)齊的解決辦法

    MySQL中出現(xiàn)亂碼和表格不對(duì)齊的解決辦法

    這篇文章給大家介紹了MySQL中出現(xiàn)亂碼和表格不對(duì)齊的解決辦法,文中通過(guò)代碼和圖文講解的非常詳細(xì),對(duì)大家的解決MySQL中出現(xiàn)亂碼和表格不對(duì)齊有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • MySQL忘記root密碼錯(cuò)誤號(hào)碼1045的解決辦法

    MySQL忘記root密碼錯(cuò)誤號(hào)碼1045的解決辦法

    這篇文章主要介紹了MySQL忘記root密碼錯(cuò)誤號(hào)碼1045的解決辦法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • MySQL不推薦使用uuid或者雪花id作為主鍵的原因分析

    MySQL不推薦使用uuid或者雪花id作為主鍵的原因分析

    在數(shù)據(jù)庫(kù)設(shè)計(jì)中,選擇適當(dāng)?shù)闹麈I類(lèi)型對(duì)于數(shù)據(jù)的存儲(chǔ)和查詢效率至關(guān)重要,在MySQL中,有些開(kāi)發(fā)者傾向于使用UUID或者雪花ID作為主鍵,以確保數(shù)據(jù)的唯一性,本文將探討在MySQL中不推薦使用UUID或者雪花ID作為主鍵的原因,并與其他主鍵類(lèi)型進(jìn)行差異化對(duì)比
    2023-11-11
  • mysql增量備份及恢復(fù)的操作方法

    mysql增量備份及恢復(fù)的操作方法

    增量備份是在全備或上次增量備份基礎(chǔ)上,只備份新增或修改的文件,減少數(shù)據(jù)量和時(shí)間,binlog記錄數(shù)據(jù)庫(kù)變更,重啟時(shí)創(chuàng)建新日志文件,增量備份復(fù)雜但減輕服務(wù)器負(fù)擔(dān),而binlog幫助精確恢復(fù)數(shù)據(jù)
    2023-09-09
  • MySQL數(shù)據(jù)庫(kù)自增主鍵的間隔不為1的解決方式

    MySQL數(shù)據(jù)庫(kù)自增主鍵的間隔不為1的解決方式

    這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)自增主鍵的間隔不為1的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 圖文詳解MySQL中的主鍵與事務(wù)

    圖文詳解MySQL中的主鍵與事務(wù)

    這篇文章主要給大家介紹了關(guān)于MySQL中主鍵與事務(wù)的相關(guān)資料,主鍵與事務(wù)是我們使用mysql中經(jīng)常遇到的,文中通過(guò)圖文以及實(shí)例代碼介紹的很詳細(xì),需要的朋友可以參考下
    2021-05-05
  • MySQL select、insert、update批量操作語(yǔ)句代碼實(shí)例

    MySQL select、insert、update批量操作語(yǔ)句代碼實(shí)例

    這篇文章主要介紹了MySQL select、insert、update批量操作語(yǔ)句代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • MySQL 億級(jí)數(shù)據(jù)導(dǎo)入導(dǎo)出及遷移筆記

    MySQL 億級(jí)數(shù)據(jù)導(dǎo)入導(dǎo)出及遷移筆記

    上周被安排做了一個(gè)MySQL億級(jí)數(shù)據(jù)的遷移,特此記錄一下,導(dǎo)入和導(dǎo)出是兩個(gè)過(guò)程,本文想詳細(xì)的介紹一下具體的使用,感興趣的小伙伴們可以參考一下
    2021-06-06
  • mysql忘記root密碼的解決辦法(針對(duì)不同mysql版本)

    mysql忘記root密碼的解決辦法(針對(duì)不同mysql版本)

    這篇文章主要介紹了mysql忘記root密碼的解決辦法(針對(duì)不同mysql版本),文章通過(guò)代碼示例和圖文結(jié)合的方式給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-06-06
  • 一文搞懂MySQL預(yù)編譯

    一文搞懂MySQL預(yù)編譯

    這篇文章主要介紹了MySQL預(yù)編譯的相關(guān)資料,文中講解非常詳細(xì),示例代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07

最新評(píng)論

鸡西市| 芜湖市| 蒙自县| 嘉义市| 桂林市| 孙吴县| 青岛市| 宜兰市| 榆中县| 沭阳县| 苗栗市| 基隆市| 天津市| 东丽区| 紫金县| 崇义县| 武宣县| 广东省| 淳安县| 志丹县| 南木林县| 莎车县| 醴陵市| 利津县| 无棣县| 博野县| 项城市| 象山县| 宁夏| 叙永县| 长治县| 临邑县| 乌恰县| 原平市| 吉安市| 双桥区| 防城港市| 靖州| 郓城县| 陇川县| 绥中县|