MGR特點
(1)基于Paxos協議和原生復制,多數節點同意即可通過事務提交
(2)具備高可用自動故障檢測,可自動切換
(3)可彈性擴展,集群自動的新增和移除節點
(4)有單主和多主模式
(5)支持多節點寫入,具備沖突檢測機制,可以適應多種應用場景需求
MGR組復制是什么
(1)主從復制是異步復制
master事務的提交不需要經過slave的確認,slave是否接收到master的binlog,master并不care。slave接收到master
binlog后先寫relay log,最后異步地去執行relay log中的sql應用到自身。由于master的提交不需要確保slave
relay log是否被正確接受,當slave接受master binlog失敗或者relay log應用失敗,master無法感知。

(2)半同步復制
基于傳統異步存在的缺陷,mysql在5.5版本推出半同步復制。可以說半同步復制是傳統異步復制的改進,在master事務的commit之前,必須確保一個slave收到relay
log并且響應給master后(從庫收到并產生 relaylog 后會向主庫發送一個 ACK 的信息包,當主庫獲得這個包后,認為從庫已經獲得 relaylog)才能進行事務的commit。但是slave對于relay log的應用仍然是異步進行的。

(3)組復制
基于傳統異步復制和半同步復制的缺陷——數據的一致性問題無法保證,MySQL官方在5.7.17版本正式推出組復制(MySQL Group Replication,簡稱MGR)。
由若干個節點共同組成一個復制組,一個事務的提交,必須經過組內大多數節點(N
/ 2 +
1)決議并通過,才能得以提交。如上圖所示,由3個節點組成一個復制組,Consensus層為一致性協議層,在事務提交過程中,發生組間通訊,由2個節點決議(certify)通過這個事務,事務才能夠最終得以提交并響應。
引入組復制,主要是為了解決傳統異步復制和半同步復制可能產生數據不一致的問題。組復制依靠分布式一致性協議(Paxos協議的變體),實現了分布式下數據的最終一致性,提供了真正的數據高可用方案(是否真正高可用還有待商榷)。其提供的多寫方案,給我們實現多活方案帶來了希望。

組復制脫離了傳統的主從模式結構,是一個具有容錯功能的集群架構,在組復制的架構中,有多個 server成員構成,并且每個成員都可以獨立執行事務,也就意味著多寫的功能,但是所有的讀寫事務必須在沖突校驗完成后才能提交,如果是只讀型的事務那么會直接提交。當某個節點上發出一個讀寫的事務準備提交時,那么這個節點就會向整個集群開始廣播這次讀寫的變更和對應的一個校驗標識符,然后會針對這個事務產生一個全局的順序號,由于是有順序號的,所以集群中的每個成員都會按照順序去執行事務的變更從而保證了數據的一致性。
如果在不同的 server 上執行了相同的操作,并且產生了事務沖突,那么校驗機制就會做成相應的判斷,通常先提交的事務先執行,后提交的回滾。所以從某種程度上來說,組復制是一種偽同步復制模式。
組復制的模式
(1)單主模式
在單主模式下,組有一個設置為讀寫模式的單主 server。 組中的所有其他成員被自動設置為只讀模式(超級只讀模式)。主服務器通常是用于引導組的第一個 server,所有其他加入的 server 自動從主服務器同步并設置為只讀。

在單主機模式下,將禁用在多主機模式下部署的某些檢查,因為系統會強制在組中每次只有一個寫入server。 例如,在單主模式下允許對具有外鍵的表進行更改,而在多主模式下不允許。 在主服務器故障時,自動選主機制選擇下一個主服務器。 通過按字典順序(使用其 UUID)來排序剩余的 server 成員并選擇列表中的第一個成員來作為下一個主服務器。
如果主服務器從組中移除,則啟動主節點選擇程序,然后從組中的其余 server 成員中選擇新的主節點。通過查看新視圖,按照詞典順序將 server 的 UUID 進行排序并選擇第一個作為主節點。選擇了新的主節點后,它將自動設置為只讀,其他輔助節點仍然為輔助節點,因此也是只讀。
(2)多主模式
多主模式,也就是所有節點都可以寫入,每個節點基本都一樣

PXC和MGR的區別
(1)執行提交
PXC 事務需要在所有節點跑一下
MGR 多數節點同意,即可執行
(2)復制
PXC 在復制上需要Gcache中緩存
MGR 直接寫binlog
(3)新增節點
新增節點PXC支持mysqldump xtrabackup
MGR直接集成復制克隆
(4)網絡中斷
網絡中斷發生時,PXC具有分區的表不可讀寫
MGR 可讀不可寫
(5)流控
MGR 寫入變慢
PXC所有節點不可寫
(6)跨平臺
跨平臺;PXC支持Linux
MGR支持所有平臺
(7)DDL
當PXC在進行DDL時,為了保證節點數據一致,此時整個集群拒絕寫操作,注意是集群內所有的表寫操作均無法提供寫服務,但是讀操作可以正常進行。
MGR 采用innodb存儲引擎,支持在線DDL單主搭建(5.7)
規劃主機
我這里用三臺虛擬機
192.168.168.101 3306
192.168.168.102 3306
192.168.168.103 3306
(1)配置host和IP的映射
在三臺主機上分別 vi /etc/hosts
mysql 的組復制依然存在解析 host 的 bug,所以我們必須在所有節點內把 host和 ip 的映射關系配置完畢。
192.168.168.101 master1
192.168.168.102 slave2
192.168.168.103 slave3

(2)關閉防火墻
查看centos7的防火墻
firewall-cmd --state
停止firewall
systemctl stop firewalld.service
禁止firewall開機啟動
systemctl disable firewalld.service

(3)快速初始化3臺mysql庫
1、壓縮包解壓
tar -xvf mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz
mv mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz /usr/local/mysql
2、配置環境變量
vi /etc/profile
export PATH=/usr/local/mysql/bin:$PATH
source /etc/profile
3、編輯mysql配置文件
vi /etc/my.cnf
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/3306/data
log_bin=/data/3306/binlog/mysql-bin
port=3306
server_id=1013306 #(另外兩臺機器 server_id=1023306\ server_id=1033306)
socket=/tmp/mysql.sock
gtid-mode=on
enforce-gtid-consistency=true
log_slave_updates=1
relay_log_info_repository=TABLE
master_info_repository=TABLE
relay_log_recovery=on
4、創建數據目錄和賦權
mkdir -p /data/3306/data
mkdir -p /data/3306/binlog
chown mysql:mysql -R /data
5、初始化
mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql --initialize-insecure --datadir=/data/3306/data --user=mysql &
6、啟動
mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &
7、登錄
mysql -u root
mysql -S /tmp/mysql3306.sock -u root(4)配置mgr參數
分別在三臺配置文件my.cnf上添加,配置后重啟生效
101上:
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.101:34901"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
102上:
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.102:34902"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
103上:
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.103:34903"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"分別將三臺庫重啟
mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &

(5)創建組復制用戶
SET SQL_LOG_BIN=0;
CREATE USER repl@'%' IDENTIFIED BY 'repl';
GRANT REPLICATION SLAVE ON *.* TO repl@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
(6)安裝組復制插件
在3套庫上都安裝
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
show plugins;

(7)啟動并引導組復制
在單主模式中我們需要默認的選擇一個節點作為主節點,并且使這個節點成為引導節點。
選擇在101主機上的 mysql 中運行以下的命令
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;SET GLOBAL group_replication_bootstrap_group=ON; 意思是打開節點的引導模式
START GROUP_REPLICATION; 意思是開啟同步
SET GLOBAL group_replication_bootstrap_group=OFF; 在我們將節點一設置為引導節點后關閉

啟動報錯,查看日志

set @@global.binlog_checksum='none';
在3套庫上都需要執行,可以寫入配置文件

可以查看到,改節點已經加入到集群中 ONLINE

在erro日志中看到到節點 1 已經通過 MGR 的內部通信管理 GCS 加入到節點中

查看是否是主節點,可以看到101主機的庫是主節點
select * from performance_schema.replication_group_members;查詢節點是否正常
8.0版本可以直接通過表performance_schemaerformance_schema.replication_group_members查看是否是主節點,在5.7中查看是否主節點需要這樣查
SELECT IF((SELECT
@@server_uuid) = (SELECT VARIABLE_VALUE FROM
performance_schema.global_status WHERE VARIABLE_NAME=
'group_replication_primary_member'), 1, 0) as is_primary_node;

測試:
為了驗證組復制是否能做到加入的節點后自動同步,我們這里可以在節點 1 上造一點數據
這里我創建了一些庫和一些表。等節點 2 和節點 3 加入組后觀察是否同步
create database test;
use test;
create table t(id int,name varchar(30),PRIMARY KEY (`id`));
insert into t select 1,'aa';

(8)節點2加入
set @@global.binlog_checksum='none';
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';
START GROUP_REPLICATION;2節點加入到集群,且不是主

如果是8.0的MGR,可以直接從這里查到是否是主

數據也自動同步過來了,驗證了組復制新加入的節點數據自動同步

(9)節點3加入
set @@global.binlog_checksum='none';
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';
START GROUP_REPLICATION;3節點加入集群,且不是主

可以查看,數據已經同步過來了,再次驗證了組復制新加入的節點數據自動同步

注意:配置文件沒有寫
loose-group_replication_single_primary_mode = true
loose-group_replication_enforce_update_everywhere_checks = false
在5.7中,開始組復制之前,可以手動配置寫入
set global group_replication_single_primary_mode=true;
set global group_replication_enforce_update_everywhere_checks = false;當然如果不寫,默認是

多主搭建
多主節點搭建基本和單主步驟一樣,只需要配置文件my.cnf額外添加,本文以下示例為單主節點搭建,多主節點搭建亦相差無幾
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks= TRUE
單主搭建(8.0)
1、壓縮包解壓
tar -xvf mysql-8.0.25-linux-glibc2.12-x86_64.tar
rm -rf /usr/local/mysql
mv mysql-8.0.25-linux-glibc2.12-x86_64 /usr/local/mysql
2、配置環境變量
vi /etc/profile
export PATH=/usr/local/mysql/bin:$PATH
source /etc/profile
3、編輯mysql配置文件
vi /etc/my.cnf
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/3306/data
log_bin=/data/3306/binlog/mysql-bin
port=3306
server_id=1013306 #(另外兩臺機器 server_id=1023306\ server_id=1033306)
socket=/tmp/mysql.sock
gtid-mode=on
enforce-gtid-consistency=true
log_slave_updates=1
relay_log_info_repository=TABLE
master_info_repository=TABLE
relay_log_recovery=on
--101----------------------------------------------------------------------------------------------------------
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.101:34901"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
--102----------------------------------------------------------------------------------------------------------
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.102:34902"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
--103----------------------------------------------------------------------------------------------------------
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name ="a876d35e-9110-11e6-a365-842b2b5909d6"
loose-group_replication_start_on_boot =off
loose-group_replication_local_address ="192.168.168.103:34903"
loose-group_replication_group_seeds ="192.168.168.101:34901,192.168.168.102:34902,192.168.168.103:34903"
loose-group_replication_bootstrap_group =off
loose-group-replication-ip-whitelist="192.168.168.101,192.168.168.102,192.168.168.103"
------------------------------------------------------------------------------------------------------------
4、創建數據目錄和賦權
mkdir -p /data/3306/data
mkdir -p /data/3306/binlog
chown mysql:mysql -R /data
5、初始化
mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql --initialize-insecure --datadir=/data/3306/data --user=mysql &
6、啟動
mysqld_safe --defaults-file=/etc/my.cnf --user=mysql &
7、登錄
mysql -u root
mysql -S /tmp/mysql3306.sock -u root
8、安裝組復制插件
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
show plugins;
9、在101上創建復制用戶
SET SQL_LOG_BIN=0;
CREATE USER repl@'%' IDENTIFIED WITH mysql_native_password BY 'repl';
GRANT REPLICATION SLAVE ON *.* TO repl@'%';
GRANT BACKUP_ADMIN ON *.* TO repl@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
10、啟動并引導組復制
在單主模式中我們需要默認的選擇一個節點作為主節點,并且使這個節點成為引導節點。
在 mysql 中運行以下的命令
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
11、依次在另外兩個節點
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';
START GROUP_REPLICATION;
如下為8.0的單主三節點MGR集群





