mysql mgr故障恢复实现_MGR实现分析 - 成员管理与故障恢复实现
MySQL Group Replication(MGR)框架讓MySQL具備了自動主從切換和故障恢復能力,舉single primary(單主)模式為例,primary作為主節(jié)點對外提供讀寫服務,是唯一的可寫節(jié)點,其他節(jié)點均為secondary節(jié)點,可提供讀服務。在傳統(tǒng)的master-slave主從復制模式下,如果master發(fā)生了crash,MySQL DBA需要手動將slave升級為新master(比如關閉只讀開關等),舊的master重啟后需執(zhí)行change master to進行復制關系重建,并執(zhí)行start slave開啟復制。如果是semi-sync半同步復制,還需要進行半同步參數(shù)配置。但在MGR模式下MySQL能自動發(fā)現(xiàn)primary crash,通過選主產(chǎn)生新的primary節(jié)點對外提供讀寫服務。舊的primary節(jié)點重啟后,DBA只需要執(zhí)行start group_replication即可將crash節(jié)點重新加入到Group中,在運維便利性和系統(tǒng)健壯性上有極大的提升。
本文分為3個部分,先分析MGR的成員管理機制,講解crash的節(jié)點如何重新加入到Group中,然后再分析該節(jié)點加入Group后如何進行故障恢復使其自身狀態(tài)從Recovery變?yōu)镺NLINE,最后分析目前存在的不足。
一、成員管理
視圖及視圖切換
MGR以組視圖(Group View,簡稱視圖)為基礎來進行成員管理。視圖指Group在一段時間內的成員狀態(tài),如果在這段時間內沒有成員變化,也就是說沒有成員加入或退出,則這段連續(xù)的時間為一個視圖,如果發(fā)生了成員加入或退出變化,則視圖也就發(fā)生了變化,MGR使用視圖ID(View ID)來跟蹤視圖的變化并區(qū)分視圖的先后時間。在進一步介紹之前,我們先看一個圖:
Group當前的視圖ViewID為83973:2,該視圖中包括2個成員,分別為DB1和DB2;一段時間后DB3節(jié)點請求加入Group,成功加入后視圖切換為83973:3,包括3個成員,分別為DB1、DB2和DB3;之后DB2節(jié)點crash而退出了Group,視圖切換為83973:4;之后DB4加入Group,視圖切換為83973:5。從上面的圖例我們可以發(fā)現(xiàn),ViewID由2部分組成,分別如下。
前綴部分:是在這個Group初始化時產(chǎn)生,為當時的時間戳,Group存活期間該值不會發(fā)生變化。所以,該字段可用于區(qū)分2個視圖是否為同一個Group的不同時間點;
序號部分:Group初始化時,第一個視圖的序號從1開始,其成員只有1個,為進行初始化的節(jié)點。以后Group出現(xiàn)任何成員的加入或退出序號都需要增一。
上面所述的是同個Group的視圖的變化情況,這里再補充說明下Group定義。一個組Group是在節(jié)點參數(shù)為group_replication_bootstrap_group為on的條件下執(zhí)行start group_replication產(chǎn)生的,如果要加入現(xiàn)有的Group,節(jié)點需要確保group_replication_bootstrap_group為off。一個節(jié)點加入Group后,需要連到其他節(jié)點使自己的數(shù)據(jù)uptodate,如果該Group其他成員都已不在線,那么就無法進行uptodate,在這種情況下,就需要設置group_replication_bootstrap_group為on來初始化新的Group。
Group的當前視圖可以通過performance_schema系統(tǒng)庫下的replication_group_member_stats表中查到,下圖表示該Group初始化時間為2018/2/7 14:54:13,已經(jīng)發(fā)生了321次視圖切換:
視圖切換實現(xiàn)
上面我們簡單一個節(jié)點加入Group后,需要連到其他節(jié)點使自己數(shù)據(jù)uptodate,那么基于什么來判斷自己的數(shù)據(jù)uptodate了呢。下面我們詳細介紹一個節(jié)點如何加入到Group中,用圖說話,如下:
一個節(jié)點請求加入Group時,其首先會根據(jù)配置的group_replication_group_seeds參數(shù)跟Group的種子成員建立TCP連接 (Gcs_xcom_control::do_join())。該種子成員會根據(jù)自己的group_replication_ip_whitelist(ip白名單)檢查是否允許新節(jié)點加入,MGR默認不限制新節(jié)點的ip。連接建立后,新節(jié)點發(fā)送請求申請加入組,如上圖左上所示;收到請求后,種子成員廣播視圖變化的消息給Group中的所有節(jié)點,包括申請加入的節(jié)點,如右上所示;各節(jié)點收到消息后開始做視圖切換。每個節(jié)點都會廣播一個狀態(tài)交換消息,每個交換消息包含了節(jié)點的當前狀態(tài)和信息,如圖左下所示。發(fā)送了交換消息后,各個節(jié)點開始接收其他節(jié)點廣播的消息,將其中的節(jié)點信息更新到本節(jié)點所維護的成員列表中。狀態(tài)交換消息像事務數(shù)據(jù)包一樣走相同的Paxos(Mencius)協(xié)議進行發(fā)送,當收到所有成員的狀態(tài)交換消息時,通信模塊將完整的新視圖封裝為視圖數(shù)據(jù)包(view_change_log_event,即vcle的前身,但沒有數(shù)據(jù)庫當前的快照版本信息),Group中的每個節(jié)點基于MGR的通信模塊將其返回給全局事務認證模塊的消息隊列(簡稱認證隊列)。至此,視圖切換即告結束。視圖切換過程中不會影響在線成員對外服務。
視圖數(shù)據(jù)包的作用
完成視圖切換只是成員加入Group要做的第一步,只是說明該成員可以接收到Group中通過Paxos協(xié)議達成共識的消息,并不意味著可以將成員設置為ONLINE(上線)對外提供服務。原因是新成員還需要進行數(shù)據(jù)同步,建立起正確的數(shù)據(jù)版本(recovery_module->start_recovery)。之后才能執(zhí)行Paxos協(xié)議消息,進而上線提供正常的用戶訪問服務。
在這過程中,視圖數(shù)據(jù)包發(fā)揮了關鍵性的作用。如上所述,視圖數(shù)據(jù)包通過Paxos放入消息隊列,那么各節(jié)點依次處理消息隊列中的數(shù)據(jù)包時就能夠發(fā)現(xiàn)視圖數(shù)據(jù)包(Plugin_gcs_events_handler::on_view_changed),將視圖數(shù)據(jù)包封裝為view_change_log_event后寫入Relay log文件中,group_replication_applier通道的并行復制線程讀取Relay log中的vcle并將其寫入到Binlog文件中。這樣,Binlog文件中的事務就被vcle劃分為多個區(qū)間,每個區(qū)間都代表一個視圖。vcle中包括了ViewID和用于進行全局事務認證模塊進行事務認證的沖突檢測數(shù)據(jù)庫?;趘cle,我們可以把節(jié)點上線前的過程劃分為2個階段,分為前一個視圖數(shù)據(jù)恢復和本視圖緩存事務執(zhí)行。第一個階段又可以細分為本地恢復和全局恢復。下面分析這三個子過程的具體實現(xiàn)。
二、故障恢復實現(xiàn)
在開始介紹前,需簡單介紹下MGR所涉及的數(shù)據(jù)復制及其通道(channel),MGR正常運行時,即Group中各節(jié)點均在線,節(jié)點間通過Paxos協(xié)議傳輸數(shù)據(jù),異地事務經(jīng)過認證后寫入group_replication_applier Relay log中,由group_replication_applier通道的復制線程負責回放。當有節(jié)點加入Group時,需要用到另一個復制通道group_replication_recovery,它是一個傳統(tǒng)的Master-Slave異步復制通道。
MGR故障恢復代碼位于MGR代碼目錄(rapid\plugin\group_replication\src)的Recovery.cc文件下,節(jié)點的故障恢復交由單獨的恢復線程(launch_handler_thread -> recovery_thread_handle)執(zhí)行。
本地恢復階段
第一步:進行故障恢復初始化,包括故障恢復線程初始化,Group成員信息初始化等。
第二步:啟動group_replication_applier復制通道。對于故障恢復場景,待加入的成員不是新節(jié)點,也就是說其曾經(jīng)加入過該節(jié)點,其group_replication_applier通道的Relay log可能還有一些Binlog未回放。所以需要先將這部分Relay log回放掉。由于有后面所述對的第三步,非Group初始化場景下,其實可以跳過回放本地恢復的環(huán)節(jié),直接從其他節(jié)點復制所需的數(shù)據(jù),但引入本地恢復的好處在于可提高恢復性能,無需在拉取這部分Binlog,提高恢復過程健壯性,減小所需Binlog被purge的風險。
確認對應通道的復制線程空閑后,阻塞(suspend)認證隊列的處理線程,即允許新的Paxos消息入隊但不進行處理。這樣,本視圖的Paxos消息會在認證隊列中堆積起來。
若該節(jié)點是Group的第一個節(jié)點,即Group初始化場景,則故障恢復結束,可將此節(jié)點置為在線狀態(tài)。
全局恢復階段
第三步:完成本地Relay log回放后,進入故障恢復第三步,即State transfer是通過group_replication_recovery復制通道從Group其他在線節(jié)點拉取本節(jié)點欠缺的非本視圖的數(shù)據(jù)。與傳統(tǒng)的Master-Slave復制配置不同,MGR中僅需為其配置賬號和密碼即可,配置方式形如:CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='rpl_pass' FOR CHANNEL 'group_replication_recovery'。顯然,該通道是基于GTID以MASTER_AUTO_POSITION的方式進行?;謴途€程隨機選擇一個在線節(jié)點(donor),調用rpl_slave.cc中的request_dump函數(shù)建立與donor的復制關系,該函數(shù)攜帶了恢復節(jié)點的gtid_executed信息。donor端會逆序遍歷其Binlog文件,通過判斷Binlog文件起始的Previous-GTIDs來找到第一個不屬于gtid_executed的事務,從該事務開始進行數(shù)據(jù)復制。
MGR實現(xiàn)了全局恢復階段的容錯能力,能夠處理異步復制過程中出現(xiàn)的絕大部分情況:
recovery_aborted:表示主動退出故障恢復過程。
on_failover:表示donor節(jié)點離開了Group,故障恢復線程選擇另一個在線節(jié)點作為donor,連上后繼續(xù)進行異步復制。該場景下,從退出的donor節(jié)點復制而來未回放的Relay log不會purge,而是完成回放后再繼續(xù)從當前donor進行復制。
donor_channel_applier_error:表示本節(jié)點回放從donor節(jié)點復制過來的事務時出錯,故障恢復線程也會選擇另一個節(jié)點作為donor繼續(xù)進行數(shù)據(jù)復制,但與on_failover不同的是,該場景下,未回放的Relay log被purge,從出錯事務位置開始從新donor節(jié)點重新拉取Binlog進行嘗試。
donor_transfer_finished:這是正常的情況,表示全局恢復已經(jīng)完成了所需數(shù)據(jù)復制??蛇M入到緩存事務執(zhí)行階段。那么如何獲知已經(jīng)復制完所需數(shù)據(jù)呢,這就用到了我們前述的vcle,復制vcle后,會判斷其攜帶的ViewID,如果其與節(jié)點當前的ViewID同等,就表示異步復制可以停止了。在開始下一步處理前,還故障恢復線程還會基于vcle初始化認證所需的沖突檢查數(shù)據(jù)庫。
除了上述情況外,還可能出現(xiàn)所選的donor無法連接(比如配置了IP白名單)或所需的Binlog已經(jīng)被purge的情況。對于該情況,故障恢復線程會選擇其他donor進行重試,可通過參數(shù)group_replication_recovery_reconnect_interval和group_replication_recovery_retry_count對重試行為進行控制,第一個參數(shù)表示重試的間隔時間,默認為1分鐘,第二個參數(shù)為重試的次數(shù), 默認為10次。
緩存事務執(zhí)行
第四步:先喚醒在第二步被阻塞的認證隊列處理線程,讓本節(jié)點逐步跟上Group中的其他節(jié)點,進而將其設置為在線(ONLINE)。那么,應該在什么時候允許節(jié)點上線呢,MGR引入?yún)?shù)group_replication_recovery_complete_at進行控制,可選TRANSACTIONS_CERTIFIED或TRANSACTIONS_APPLIED。分別表示認證隊列為空或回放完所有已認證的事務時。雖然判斷條件很明確,但實際場景下代碼實現(xiàn)卻較為困難,因為負載可能是持續(xù)的,狀態(tài)是動態(tài)變化,不會存在靜態(tài)的事務均已認證或均已回放的狀態(tài)。
對于單主模式,在開始處理認證隊列之前,需要先將沖突檢測標志位開啟,這樣在緩存的隊列請求時就會將事務攜帶的快照版本跟沖突檢測數(shù)據(jù)庫版本進行對比,決定事務是回滾還是提交。此時開啟沖突檢測的原因是緩存的事務有部分是在primary節(jié)點回放之前視圖產(chǎn)生的Relay log過程時執(zhí)行的,也就是說,事務執(zhí)行的時候,其基于的數(shù)據(jù)并不是最新的數(shù)據(jù),所以可能會被回滾,如果未開啟沖突檢測就會導致數(shù)據(jù)不一致。這里需要說明一點,就是無論是否開啟沖突檢測,經(jīng)過Paxos發(fā)送的消息都會進入認證隊列,然后依次進行處理。代碼實現(xiàn)上,沖突檢測只是認證的一個環(huán)節(jié),除此之外,還需要為事務確定gtid,并確保相同的事務在各個節(jié)點產(chǎn)生的gtid是相同的。
成員上線與出錯處理
第五步:在達到了group_replication_recovery_complete_at所確定的條件后,發(fā)送Recovery_message::RECOVERY_END_MESSAGE消息,通知Group中的各個節(jié)點,將該節(jié)點設置為在線狀態(tài)。
第六步:在故障恢復全過程中,若遇到了無法繼續(xù)的情況或錯誤,比如recovery_aborted被置位或恢復所需的數(shù)據(jù)在其他節(jié)點均已被Purge或等待上線時回放出錯等,則先將該節(jié)點置為ERROR狀態(tài),確認該節(jié)點復制相關線程退出了,節(jié)點向Group發(fā)送leave信息退出Group,而不是置為ERROR狀態(tài)候仍留在Group中。這是跟MongoDB Replica Set等其他多節(jié)點數(shù)據(jù)庫系統(tǒng)不一樣的地方。
第七步:不管是否出錯,均需要重置故障恢復相關的參數(shù),并銷毀故障恢復線程。
三、MGR故障恢復實現(xiàn)的不足
1、隨機選擇donor節(jié)點:早期的MGR版本按照節(jié)點設置group_replication_group_seeds參數(shù)中的種子節(jié)點順序來選擇donor節(jié)點,若各節(jié)點的參數(shù)配置一致,則存在同一個節(jié)點被反復選擇為donor節(jié)點,會導致該節(jié)點負載過大而出現(xiàn)復制延遲等問題,不利Group中各節(jié)點負載的均衡。當前的MGR版本已將其調整為隨機選擇donor,有了很大進步,但仍可以進一步優(yōu)化,就是存在多個可選的節(jié)點情況下,單主模式先排除primary節(jié)點,多主模式下排除本地負載壓力最大的節(jié)點;
2、本視圖事務緩存機制:MGR在節(jié)點進行全局恢復時,將本視圖產(chǎn)生的消息緩存在認證隊列中,若節(jié)點落后較多,需較長時間完成全局恢復,若Group的負載較高,會在認證隊列中堆積大量的消息,這些消息位于內存中,容易出現(xiàn)因為內存不足而OOM??煽紤]的優(yōu)化方案是基于一定的策略將緩存的消息臨時寫到系統(tǒng)表中,將壓力轉移到磁盤上。
3、Binlog被purge處理:相比Percona基于Galera封裝的Percona XtraDB Cluster(PXC),MongoDB Replica Set(ReplSet)方案,MGR目前還未提供節(jié)點全量恢復方案。即可往Group中加入一個全新的節(jié)點,由MGR來負責從其他節(jié)點拷貝全量數(shù)據(jù)(State Snapshot Transfer,SST),并通過增量復制(Incremental State transfers,IST)直至將節(jié)點置為上線狀態(tài)。PXC是個解決方案套件,采用xtrabackup來實現(xiàn)SST,ReplSet是進程,采用邏輯拷貝的方式實現(xiàn)Initial Sync。MGR可參考ReplSet來實現(xiàn)。
4、成員類型單一:MGR目前僅提供Primary和Secondary兩種成員類型,不支持Arbiter,Hidden等類型,也不支持像MongoDB和X-Cluster等其他數(shù)據(jù)庫系統(tǒng)設置豐富的成員屬性。
參考資料:
3、MySQL 5.7.20、MySQL 8.0.4源碼
4、MySQL運維內參 27章MySQL Group Replication
轉:溫正湖
總結
以上是生活随笔為你收集整理的mysql mgr故障恢复实现_MGR实现分析 - 成员管理与故障恢复实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信小程序轮播中的current_微信小
- 下一篇: java swing最小化_Java s