MySQL MGR 高可用集群搭建過程詳解
1、MGR 前置介紹
阿里云RDS集群方案用的就是MGR模式!

1.1、什么是 MGR
- MGR(MySQL Group Replication)是MySQL 5.7.17版本誕生的,是MySQL自帶的一個插件,可以靈活部署。
- 保證數據一致性又可以自動切換,具備故障檢測功能、支持多節(jié)點寫入。
- 集群是多個MySQL Server節(jié)點共同組成的分布式集群,每個Server都有完整的副本,它是基于ROW格式的二進制日志文件和GTID特性。
1.2、MGR 優(yōu)點
- 強一致性:基于原生復制及paxos協(xié)議的組復制技術,并以插件的方式提供,提供一致數據安全保證。
- 高容錯性:只要不是大多數節(jié)點壞掉就可以繼續(xù)工作,有自動檢測機制,當不同節(jié)點產生資源爭用沖突時,不會出現錯誤,按照先到者優(yōu)先原則進行處理,并且內置了自動化腦裂防護機制。
- 高擴展性:節(jié)點的新增和移除都是自動的,新節(jié)點加入后,會自動從其他節(jié)點上同步狀態(tài),直到新節(jié)點和其他節(jié)點保持一致,如果某節(jié)點被移除了,其他節(jié)點自動更新組信息,自動維護新的組信息。
- 高靈活性:有單主模式和多主模式。單主模式下,會自動選主,所有更新操作都在主上進行;多主模式下,所有server都可以同時處理更新操作。工作中優(yōu)先使用單主模式!
1.3、MGR 缺點
- 僅支持InnoDB表,并且每張表一定要有一個主鍵,用于做write set的沖突檢測。
- 必須打開GTID特性,二進制日志格式必須設置為ROW,用于選主與write set;主從狀態(tài)信息存于表中(–master-info-repository=TABLE 、–relay-log-inforepository=TABLE),–log-slave-updates打開。
- MGR不支持大事務,事務大小最好不超過143MB,當事務過大,無法在5秒的時間內通過網絡在組成員之間復制消息,則可能會懷疑成員失敗了,然后將其驅逐出局。
- 目前一個MGR集群最多支持9個節(jié)點。
- 不支持外鍵于save point特性,無法做全局間的約束檢測與部分事務回滾。
- 二進制日志不支持Binlog Event Checksum。
1.4、MGR 適用場景
- 金融交易、重要數據存儲、對主從一致性要求高的場景。
- 核心數據總量未過億。
- 讀多寫少,如:互聯(lián)網電商。
2、MySQL MGR 搭建流程
2.1、環(huán)境準備
本次集群搭建,我使用3臺阿里云ECS服務器(CentOS 7.9,2核2G,20G硬盤),每臺服務器都分配公網IP,開放安全組:22(SSH)、3306(MySQL)、24901(MGR)。我的服務器配置如下:
Master服務器(hostname:n0):172.21.180.98
Slave服務器1(hostname:n1):172.21.180.99
Slave服務器2(hostname:n2):172.21.180.100

2.2、搭建流程
2.2.1、配置系統(tǒng)環(huán)境
將Hosts文件寫入n0/n1/n2節(jié)點與內網IP對應關系,后面配置采用域名訪問:
# 3臺服務器都執(zhí)行 sudo cat > /etc/hosts <<-'EOF' 172.21.180.98 n0 172.21.180.99 n1 172.21.180.100 n2 EOF
分別為三臺服務器依次設置主機名稱,三臺服務器執(zhí)行命令:
# 第1臺服務器 hostnamectl set-hostname n0 # 第2臺服務器 hostnamectl set-hostname n1 # 第3臺服務器 hostnamectl set-hostname n2
2.2.2、安裝 MySQL
下載 MySQL 官方YUM倉庫源(這個并不是安裝MySQL):
# 3臺服務器都執(zhí)行 cd /home/ wget --no-check-certificate https://repo.mysql.com/mysql80-community-release-el7-5.noarch.rpm yum localinstall -y mysql80-community-release-el7-5.noarch.rpm
修改倉庫配置,將下圖中gpgcheck置為0:
vi /etc/yum.repos.d/mysql-community.repo

安裝 MySQL 8.0.26:
# 3臺服務器都執(zhí)行 yum install -y mysql-community-server-8.0.26
2.2.3、配置啟動 MySQL
主節(jié)點n0執(zhí)行:直接CV就行,不要墨跡!
# 修改 MySQL 配置 sudo cat >> /etc/my.cnf <<-'EOF' # 使用mysql_native_password密碼策略,防止navicat連不上mysql8 default_authentication_plugin=mysql_native_password # 設置MySQL插件目錄:MGR基于插件,必須設置插件路徑 plugin_dir=/usr/lib64/mysql/plugin # 服務器編號,Master=1 server_id=1 # 開啟binlog的GTID模式(MGR強制要求) gtid_mode=ON # 開啟后MySQL只允許能夠保障事務安全,并且能夠被日志記錄的SQL語句被執(zhí)行 enforce_gtid_consistency=ON # 關閉binlog校驗(MGR強制要求) binlog_checksum=NONE # 定義用于事務期間哈希寫入提取的算法,組復制模式下必須設置為 XXHASH64。 transaction_write_set_extraction=XXHASH64 # 確定組復制恢復時是否應該應用 SSL,通常設置為“開”,但默認設置為“關”。 loose-group_replication_recovery_use_ssl=ON # 服務器實例所在復制組名稱,必須是有效的 UUID,所有節(jié)點必須相同。 loose-group_replication_group_name="bbbbbbbb-bbbb-cccc-dddd-eeeeeeeeeeee" # 確定服務器是否應該在服務器啟動期間啟動組復制。 loose-group_replication_start_on_boot=OFF # 為復制組中其他的成員提供的網絡地址,指定為“主機:端口”的格式化字符串。 # 很多人想當然認為端口應該是3306,起始不然,MGR需要開啟新端口24901同步交換 # 所以這里不要寫錯,同時,前面我們配置了hosts文件做了主機名與IP的映射,這里直接寫主機名即可 loose-group_replication_local_address="n0:24901" # 用于建立新成員到組的連接組成員列表。 # 這個列表指定為由分隔號間隔的組成員網絡地址列表,類似 host1:port1、host2:port2 的格式。 # 同樣采用n0~n2的主機名替代 loose-group_replication_group_seeds="n0:24901,n1:24901,n2:24901" # 配置此服務器為引導組,這個選項必須僅在一臺服務器上設置, # 并且僅當第一次啟動組或者重新啟動整個組時。成功引導組啟動后,將此選項設置為關閉。 loose-group_replication_bootstrap_group=OFF EOF
從節(jié)點n1執(zhí)行:直接CV就行,不要墨跡!
sudo cat >> /etc/my.cnf <<-'EOF' default_authentication_plugin=mysql_native_password plugin_dir=/usr/lib64/mysql/plugin # 設置唯一的服務器編號 server_id=2 gtid_mode=ON enforce_gtid_consistency=ON binlog_checksum=NONE # 這個參數決定primary節(jié)點到secondary節(jié)點的請求是否為基于 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 # 設置本機地址n1:24901 loose-group_replication_local_address="n1:24901" loose-group_replication_group_seeds="n0:24901,n1:24901,n2:24901" loose-group_replication_bootstrap_group=OFF EOF
從節(jié)點n2執(zhí)行:直接CV就行,不要墨跡!
sudo cat >> /etc/my.cnf <<-'EOF' default_authentication_plugin=mysql_native_password plugin_dir=/usr/lib64/mysql/plugin #設置唯一的服務器編號 server_id=3 gtid_mode=ON enforce_gtid_consistency=ON binlog_checksum=NONE #這個參數決定primary節(jié)點到secondary節(jié)點的請求是否為基于 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 #設置本機地址n2:24901 loose-group_replication_local_address="n2:24901" loose-group_replication_group_seeds="n0:24901,n1:24901,n2:24901" loose-group_replication_bootstrap_group=OFF EOF
三臺服務器,依次啟動 MySQL
# 3臺服務器都執(zhí)行 systemctl start mysqld
2.2.4、修改密碼、設置主從同步
三臺服務器,依次通過該命令,獲取數據庫連接密碼:
# 獲取數據庫密碼 grep 'temporary password' /var/log/mysqld.log
三臺服務器,連接到數據庫控制臺中:
# 連接數據庫 mysql -uroot -p'密碼'
三臺數據庫控制臺中,都執(zhí)行下述命令(3臺服務器都執(zhí)行):
# 修改root密碼為asAS123456! ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'asAS123456!'; # 創(chuàng)建rpl_user賬戶,此賬戶用于實現主從數據同步 CREATE USER rpl_user@'%' IDENTIFIED BY 'asAS123456!'; # 賦予主從同步權限 GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; # 創(chuàng)建一個遠程連接用戶,這個用戶用在Navcate、JDBC登錄的時候,直接用root登錄不好 create user 'remote'@'%' identified with mysql_native_password by 'asAS123456!'; # 為remote用戶賦予所有數據庫資源的訪問權限,熟悉grant的小伙伴可以自己調整 grant all privileges on *.* to remote@'%'; # 讓剛才的修改生效 FLUSH PRIVILEGES; # 刪除已產生的Binlog # 一定要RESET MASTER,它會刪除剛才已產生的Binlog # 因為剛才Binglog包含創(chuàng)建用戶這種高權限操作,用于主從同步的rpl_user賬戶是沒有權限執(zhí)行的 # 這就會導致RelayLog重放無法正確執(zhí)行,導致從屬服務器卡死在"RECEVERING"狀態(tài) # 利用RESET MASTER刪除這些無法執(zhí)行的binlog,就沒問題了 RESET MASTER;
2.2.5、安裝 MGR 插件
在三臺服務器的MySQL控制臺中,安裝MGR插件,執(zhí)行命令:
# 3臺服務器都執(zhí)行 INSTALL PLUGIN group_replication SONAME 'group_replication.so';
在主服務器的MySQL控制臺上,執(zhí)行下述命令:
# 注意:只在主服務器上運行 # 我們在 primary.cnf 配置文件中把 group_replication_bootstrap_group 參數設置成 OFF # 在 primary 服務器啟動時并不會直接啟動復制組,通過下面的命令動態(tài)的開啟復制組是我們的集群更安全 SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=OFF;
在兩個從服務器MySQL控制臺上,執(zhí)行下述命令:
# 指定主從賬戶與指定通信頻道 CHANGE MASTER TO MASTER_USER="rpl_user", MASTER_PASSWORD="asAS123456!" FOR CHANNEL 'group_replication_recovery'; # 開啟組網數據同步 START GROUP_REPLICATION;
當兩個從節(jié)點都運行完畢后,運行下面SQL結果進行驗證:
SELECT * FROM performance_schema.replication_group_members;
出現以下情況,每個節(jié)點都是ONLINE狀態(tài),說明集群搭建成功:

3、MySQL MGR 故障轉移
上面已經將MySQL MGR集群搭建完畢,并且節(jié)點都是ONLINE狀態(tài)。

3.1、主節(jié)點n0下線,重新選舉
首先,在主服務器n0上執(zhí)行停止mysql命令,如下:
systemctl stop mysqld;
此時,在從節(jié)點n1查看集群狀態(tài)發(fā)現,n1被選舉為主節(jié)點:

這是由于MGR集群選舉策略為:
- 優(yōu)先低版本節(jié)點
- 版本一樣,優(yōu)先權重大的節(jié)點
- 版本與權重一樣,按照 server uuid 的字母順序選主
在n1從節(jié)點上,通過命令查看故障轉移日志:
# 查看MySQL日志 tail -n 50 /var/log/mysqld.log
n1日志解析如下:
# n0:3306(主節(jié)點n0)從組中被移除掉 [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: n0:3306' # 重新選舉新的 Primary 主節(jié)點 [System] [MY-011500] [Repl] Plugin group_replication reported: 'Primary server with address n0:3306 left the group. Electing new Primary.' # n1:3306(從節(jié)點n1)被選舉為主節(jié)點,執(zhí)行之前未完成的事務處理 [System] [MY-011507] [Repl] Plugin group_replication reported: 'A new primary with address n1:3306 was elected. The new primary will execute all previous group transactions before allowing writes.' # 組成員目前只剩 n1:3306, n2:3306 [System] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to n1:3306, n2:3306 on view 17172171443362674:4.' # 關閉 n1 節(jié)點的只讀狀態(tài) [System] [MY-013731] [Repl] Plugin group_replication reported: 'The member action "mysql_disable_super_read_only_if_primary" for event "AFTER_PRIMARY_ELECTION" with priority "1" will be run.' # 設置 super_read_only=OFF [System] [MY-011566] [Repl] Plugin group_replication reported: 'Setting super_read_only=OFF.' # 當前節(jié)點(n1)以主節(jié)點身份工作 [System] [MY-011510] [Repl] Plugin group_replication reported: 'This server is working as primary member.'
在n2從節(jié)點上,通過命令查看故障轉移日志:
# 查看MySQL日志 tail -n 50 /var/log/mysqld.log
n2日志解析如下:
# n0:3306(主節(jié)點n0)從組中被移除掉 [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: n0:3306' # 重新選舉新的 Primary 主節(jié)點 [System] [MY-011500] [Repl] Plugin group_replication reported: 'Primary server with address n0:3306 left the group. Electing new Primary.' # n1:3306(從節(jié)點n1)被選舉為主節(jié)點,執(zhí)行之前未完成的事務處理 [System] [MY-011507] [Repl] Plugin group_replication reported: 'A new primary with address n1:3306 was elected. The new primary will execute all previous group transactions before allowing writes.' # 組成員目前只剩 n1:3306, n2:3306 [System] [MY-011503] [Repl] Plugin group_replication reported: 'Group membership changed to n1:3306, n2:3306 on view 17172171443362674:4.' # 當前節(jié)點(n2)作為主節(jié)點(n1)的從成員身份工作 [System] [MY-011511] [Repl] Plugin group_replication reported: 'This server is working as secondary member with primary member address n1:3306.'
3.2、新主節(jié)點n1下線,集群不可用
當在新晉升的主節(jié)點n1上執(zhí)行停止MySQL操作:
systemctl stop mysqld;
此時,在n2上通過命令查看發(fā)現,n1主節(jié)點盡管已經下線,但n2查看集群狀態(tài)時還在顯示,因為只有1個節(jié)點的情況下,少于n/2+1的規(guī)則,導致整體 MGR 集群失效,n2節(jié)點無法產生重新選舉,同時n2的日志也不會有任何新內容產生:
SELECT * FROM performance_schema.replication_group_members;

3.3、恢復 MGR 集群
恢復流程很簡單,先將三臺服務器的MySQL各自重啟:
# 3臺服務器都執(zhí)行 systemctl restart mysqld;
然后重復執(zhí)行 2.2.4 ~ 2.2.5 章節(jié)流程即可恢復 MGR 集群。
4、單主模式和多主模式
4.1、模式介紹
4.1.1、單主模式
在單主模式下, 組復制具有自動選主功能,每次只有一個 server成員可以作為主節(jié)點。
單主模式 group 內只有一臺節(jié)點可寫可讀,其他節(jié)點只可以讀。對于group的部署,需要先跑起primary主節(jié)點,然后再跑起其他的節(jié)點,并把這些節(jié)點加進group。其他的節(jié)點就會自動同步primary節(jié)點上面的變化,然后將自己設置為只讀模式。
當primary主節(jié)點意外宕機或者下線,在滿足大多數節(jié)點存活的情況下,group內部發(fā)起選舉,選出下一個可用的讀節(jié)點,提升為primary節(jié)點。

4.1.2、多主模式
在多主模式下,所有的 MySQL 節(jié)點都可以同時接受讀寫操作。group內的所有節(jié)點都是primary主節(jié)點,同時可以進行讀寫操作,并且數據是最終一致的。

4.2、模式切換
之前我們搭建的 MySQL MGR 集群就是單主模式(默認),那么如何切換為多主模式呢?按照如下操作進行。
4.2.1、單主 ——> 多主
從 n0 ~ n2 停止組復制,開啟多主模式(3個節(jié)點都執(zhí)行):
# 停止組復制 stop group_replication; # 是否啟用單主模式,默認ON,OFF代表多主 set global group_replication_single_primary_mode=OFF; # 是否開啟條件檢查,因為多主的約束更為嚴格,不符合要求的直接拒絕 # 不支持外鍵的級聯(lián)操作 # 不支持“串行化Serializable” set global group_replication_enforce_update_everywhere_checks=ON;
在 n0 主節(jié)點啟用組復制:
# 只在 n0 上執(zhí)行 SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=OFF;
在 n1,n2 節(jié)點上啟用組復制:
# 只在 n1, n2 上執(zhí)行 START GROUP_REPLICATION;
此時,可以看到三臺MySQL都是主節(jié)點:
SELECT * FROM performance_schema.replication_group_members;

4.2.2、多主 ——> 單主
從 n0 ~ n2 停止組復制,開啟多主模式(3個節(jié)點都執(zhí)行):
# 停止組復制 stop group_replication; # 是否開啟條件檢查,因為多主的約束更為嚴格,不符合要求的直接拒絕 # 不支持外鍵的級聯(lián)操作 # 不支持“串行化Serializable” set global group_replication_enforce_update_everywhere_checks=OFF; # 是否啟用單主模式,默認ON,OFF代表多主 set global group_replication_single_primary_mode=ON;
在 n0 主節(jié)點啟用組復制:
# 只在 n0 上執(zhí)行 SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=OFF;
在 n1,n2 節(jié)點上啟用組復制:
# 只在 n1, n2 上執(zhí)行 START GROUP_REPLICATION;
此時,可以看到三臺MySQL變成了主從模式:
SELECT * FROM performance_schema.replication_group_members;

到此這篇關于MySQL MGR 高可用集群搭建過程詳解的文章就介紹到這了,更多相關mysql mgr高可用集群內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

