#作者:stackofumbrella
文章目錄
- 簡介
- MGR優點
- MGR缺點
- MGR適用場景
- 單主模式和多主模式
- 組復制介紹
- 組復制插件架構圖
- 單主模式
- 多主模式
- 配置主機名解析
- 安裝MGR插件
- MGR故障轉移
- 恢復MGR集群
簡介
MGR(MySQL Group Replication)是MySQL 5.7.17版本誕生的,是MySQL自帶的一個插件,可以靈活部署。
保證數據一致性又可以自動切換,具備故障檢測功能、支持多節點寫入。
集群是多個MySQL Server節點共同組成的分布式集群,每個Server都有完整的副本,它是基于ROW格式的二進制日志文件和GTID特性。
MGR優點
強一致性:基于原生復制及paxos協議的組復制技術,并以插件的方式提供,提供一致的數據安全保證。
高容錯性:只要不是大多數節點壞掉就可以繼續工作,有自動檢測機制,當不同節點產生資源爭用沖突時,不會出現錯誤,按照先到者優先原則進行處理,并且內置了自動化腦裂防護機制。
高擴展性:節點的新增和移除都是自動的,新節點加入后,會自動從其他節點上同步狀態,直到新節點和其他節點保持一致,如果某節點被移除了,其他節點自動更新組信息,自動維護新的組信息。
靈活性:有單主模式和多主模式。單主模式下會自動選主,所有更新操作都在主上進行;多主模式下,所有server都可以同時處理更新操作。優先使用單主模式。
MGR缺點
-
僅支持InnoDB表,并且每張表一定要有一個主鍵,用于做write set的沖突檢測。
必須打開GTID特性,二進制日志格式必須設置為ROW,用于選主與write set;主從狀態信息存于表中(-master-info-repository=TABLE 、-relay-log-inforepository=TABLE),-log-slave-updates打開。 -
MGR不支持大事務,事務大小最好不超過143MB,當事務過大,無法在5秒的時間內通過網絡在組成員之間復制消息,則可能會懷疑成員失敗了,然后將其驅逐出局。
目前一個MGR集群最多支持9個節點。 -
不支持外鍵于save point特性,無法做全局間的約束檢測與部分事務回滾。
二進制日志不支持Binlog Event Checksum。
MGR適用場景
- 金融交易、重要數據存儲、對主從一致性要求高的場景。
- 核心數據總量未過億。
- 讀多寫少,如:互聯網電商。
單主模式和多主模式
組復制介紹
MGR對屬于同一組中的服務器自動進行協調。對于要提交的事務,組成員必須就全局事務序列中給定事務的順序達成一致,提交或回滾事務由每個服務器單獨完成(即每臺服務器都可以寫數據或讀數據),但所有服務器都必須做出相同的決定。如果存在網絡分區,導致成員無法達成事先定義的分割策略,則在解決此問題之前系統不會繼續進行,這是一種內置的自動裂腦保護機制。
MGR由組通信系統(Group Communication System ,GCS) 協議支持。該系統提供故障檢測機制、組成員服務以及安全且有序的消息傳遞。
組復制插件架構圖
MySQL組復制是一個MySQL插件,它基于常規的MySQL復制,利用了基于行格式的二進制日志和GTID等特性。下圖是MySQL組復制的整體框架圖。
- 從上圖的頂端開始,有一系列的API控制組復制插件如何和MySQL Server進行交互(圖中灰色方框)。
- 中間有一些接口可以使信息從MySQL Server流向組復制插件,反之亦然。這些接口將MySQL Server核心部分和插件隔離開來。在Server到插件的方向上,傳遞一些通知信息,例如server正在啟動,server正在恢復,server已準備好接收連接,server將要提交事務等等。另一方向,即插件到server的方向上,插件會通知server對事務進行提交,終止正在進行的事務,將事務放進relay-log中排隊等等。
- 從API往下是一些響應組件,當通知信息路由到它們身上時就響應。capture組件負責跟蹤正在執行的事務的上下文信息。applier組件負責在本節點上執行遠程傳輸來的事務。recovery組件負責管理分布式恢復過程,還負責在節點加入組時選擇donor,編排追趕過程以及對選擇donor失敗時的反應。
- 繼續向下,replication協議模塊包含了特定的復制協議邏輯。它負責探測沖突,在組中接收和傳播事務。
- 后兩層是組內通信系統(GCS)的API(第一個綠色方框),以及一個基于Paxos組通信引擎的實現(implementation)(第二個綠色方框)。GCS API是組內通信API,它是一個上層API,它抽象了構建一個復制狀態所需的屬性,它從插件的更上層解耦了消息傳遞層。
- 組通信引擎負責處理組內成員的通信。
單主模式
在單主模式下,組復制具有自動選主功能,group內只有一臺節點可寫可讀,其他節點只可以讀。對于group的部署,需要先跑起primary主節點,然后再開啟其他節點,并把這些節點加進group。其他的節點就會自動同步primary節點上面的變化,然后設置為只讀模式。
當primary主節點意外宕機或下線,在滿足大多數節點存活的情況下,group內部發起選舉,選出下一個可用的讀節點提升為primary節點。
多主模式
在多主模式下,所有的MySQL節點都可以同時接受讀寫操作。group內的所有節點都是primary主節點,同時可以進行讀寫操作,并且數據是最終一致的。在多主模式下,不支持SERIALIZABLE事務隔離級別,且不能完全支持級聯外鍵約束。
在mysql多主模式下,在組復制中通過Group Replication Protocol協議及Paxos協議,形成的整體高可用解決方案同時增加了certify的概念,負責檢查事務是否允許提交,是否與其它事務存在沖突。Group Replication是由多個節點共同組成一個數據庫集群,每個節點都可以單獨執行事務,但是readwrite(rw)的操作只有在組內驗證后才可以commit,Read-only (RO)事務是不需要驗證可以立即執行,當一個事務在一個節點上提交之前,會在組內自動進行原子性的廣播,告知其他節點變更了什么內容,執行了什么事務,然后為該事務建立一個全局的排序。最終這意味著所有的服務器都以相同的順序接收相同的事務集。因此,所有服務器都按照相同的順序應用相同的變更集,因此它們在組中保持一致。
配置主機名解析
$ sudo vim /etc/hosts
192.168.1.46 mysqlmaster
192.168.1.47 mysqlslave1
192.168.1.48 mysqlslave2
192.168.1.51 mysqlproxy
安裝MGR插件
查找插件位置
$ sudo find / -name “group_replication.so”
主庫配置
在主庫原有配置上增加如下配置
# 設置MySQL插件目錄:MGR基于插件,必須設置插件路徑
plugin_dir=/usr/lib/mysql/plugin
# 開啟binlog的GTID模式(MGR強制要求)
gtid_mode=ON
# 開啟后MySQL只允許能夠保障事務安全,并且能夠被日志記錄的SQL語句被執行
enforce_gtid_consistency=ON
# 關閉binlog校驗(MGR強制要求)
binlog_checksum=NONE# 定義用于事務期間哈希寫入提取的算法,組復制模式下必須設置為XXHASH64。
transaction_write_set_extraction=XXHASH64
# 服務器實例所在復制組名稱,必須是有效的UUID,所有節點必須相同。
loose-group_replication_group_name="bbbbbbbb-bbbb-cccc-dddd-eeeeeeeeeeee"
# 確定服務器是否應該在服務器啟動期間啟動組復制。
loose-group_replication_start_on_boot=OFF# 為復制組中其他的成員提供的網絡地址,指定為“主機:端口”的格式化字符串。
# 很多人想當然認為端口應該是3306,其實不然,MGR需要開啟新端口24901同步交換
# 所以這里不要寫錯,可以配置主機名或IP地址
loose-group_replication_local_address="192.168.1.46:24901"# 用于建立新成員到組的連接組成員列表。
# 這個列表指定為由分隔號間隔的組成員網絡地址列表,類似host1:port1、host2:port2的格式。
loose-group_replication_group_seeds="192.168.1.46:24901,192.168.1.47:24901,192.168.1.48:24901"# 配置此服務器為引導組,這個選項必須僅在一臺服務器上設置,
# 并且僅當第一次啟動組或重新啟動整個組時。成功引導組啟動后,將此選項設置為關閉。
loose-group_replication_bootstrap_group=OFF
slave1從庫配置
plugin_dir=/usr/lib/mysql/plugingtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE# 這個參數決定primary節點到secondary節點的請求是否為基于RSA密鑰對的密碼交換所需的公鑰
loose-group_replication_recovery_get_public_key=ON
loose-group_replication_recovery_use_ssl=ON
loose-group_replication_group_name="bbbbbbbb-bbbb-cccc-dddd-eeeeeeeeeeee"
loose-group_replication_start_on_boot=OFF# 設置slave1節點本機地址192.168.1.47:24901
loose-group_replication_local_address="192.168.1.47:24901"
loose-group_replication_group_seeds="192.168.1.46:24901,192.168.1.47:24901,192.168.1.48:24901"
loose-group_replication_bootstrap_group=OFF
slave2從庫配置
plugin_dir=/usr/lib/mysql/plugingtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE# 這個參數決定primary節點到secondary節點的請求是否為基于RSA密鑰對的密碼交換所需的公鑰
loose-group_replication_recovery_get_public_key=ON
loose-group_replication_recovery_use_ssl=ON
loose-group_replication_group_name="bbbbbbbb-bbbb-cccc-dddd-eeeeeeeeeeee"
loose-group_replication_start_on_boot=OFF# 設置slave2本機地址192.168.1.48:24901
loose-group_replication_local_address="192.168.1.48:24901"
loose-group_replication_group_seeds="192.168.1.46:24901,192.168.1.47:24901,192.168.1.48:24901"
loose-group_replication_bootstrap_group=OFF
重啟各個節點
$ sudo systemctl restart mysql
導入插件,在每個節點都執行
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
在主服務器的MySQL上執行下述命令
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
在兩個從服務器上執行下述命令,執行之前應關閉MySQL主從復制線程
# 關閉復制線程
STOP SLAVE;# 指定主從賬戶與指定通信頻道
CHANGE MASTER TO MASTER_USER="replica", MASTER_PASSWORD="123456" FOR CHANNEL 'group_replication_recovery';# 開啟組網數據同步
START GROUP_REPLICATION;
查看成員狀態信息
SELECT * FROM performance_schema.replication_group_members;
MGR故障轉移
主節點下線重新選舉
$ sudo systemctl stop mysql
在slave1節點查看集群狀態
SELECT * FROM performance_schema.replication_group_members;
查看master的日志
查看slave1的日志
查看slave2的日志
可以看到slave1已經成為主庫,由此可以說明MGR的選舉策略為:
- 優先低版本節點
- 版本一樣,優先權重大的節點
- 版本與權重一樣,按照server uuid的字母順序選主
新主節點slave1下線,集群不可用
$ sudo systemctl stop mysql
SELECT * FROM performance_schema.replication_group_members;
在slave2上通過命令查看發現,slave1新主節點盡管已經下線,但slave2還在線,因為只有1個節點的情況下,少于n/2+1的規則,導致整體MGR集群失效,slave2節點無法產生選舉
恢復MGR集群
只需要將三臺服務器的MySQL分別重啟,然后按照啟動復制組的順序執行命令即可恢復