一. 背景介紹
基於傳統異步復制和半同步復制的缺陷——數據的一致性問題無法保證,MySQL官方在5.7.17版本正式推出組復制(MySQL Group Replication,簡稱MGR)。
由若干個節點共同組成一個復制組,一個事務的提交,必須經過組內大多數節點(N / 2 + 1)決議並通過,才能得以提交。如上圖所示,由3個節點組成一個復制組,Consensus層為一致性協議層,在事務提交過程中,發生組間通訊,由2個節點決議(certify)通過這個事務,事務才能夠最終得以提交並響應。
引入組復制,主要是為了解決傳統異步復制和半同步復制可能產生數據不一致的問題。組復制依靠分布式一致性協議(Paxos協議的變體),實現了分布式下數據的最終一致性,提供了真正的數據高可用方案(是否真正高可用還有待商榷)。其提供的多寫方案,給我們實現多活方案帶來了希望。
1.MGR特點
MySQL Group Replication(MGR)是MySQL官方在5.7.17版本引進的一個數據庫高可用與高擴展的解決方案,以插件形式提供,實現了分布式下數據的最終一致性,總結MGR特點如下:
- 高一致性:基於分布式paxos協議實現組復制,保證數據一致性;
- 高容錯性:自動檢測機制,只要不是大多數節點都宕機就可以繼續工作,內置防腦裂保護機制;
- 高擴展性:節點的增加與移除會自動更新組成員信息,新節點加入后,自動從其他節點同步增量數據,直到與其他節點數據一致;
- 高靈活性:提供單主模式和多主模式,單主模式在主庫宕機后能夠自動選主,所有寫入都在主節點進行,多主模式支持多節點寫入。
2.組復制故障檢測
故障檢測是提供關於哪些 server 可能已死的信息(猜測)的分布式服務。 某個 server 無響應時觸發猜測,組中其余成員進行協調決定以排除給定成員。如果某個 server 與組的其余成員隔離,則它會懷疑所有其他 server 都失敗了。由於無法與組達成協議(因為它無法確保仲裁成員數),其懷疑不會產生后果。當服務器以此方式與組隔離時,它無法執行任何本地事務。 在線 server 列表通常稱為視圖,新成員server的加入離開,無論是自願還是被迫的離開,該組都會動態地重新規划其配置,並觸發視圖更新。
3.組復制的限制
- 存儲引擎必須為Innodb,即僅支持InnoDB表,並且每張表一定要有一個主鍵,用於做write set的沖突檢測;
- 每個表必須提供主鍵;
- 只支持ipv4,網絡需求較高;
- 必須打開GTID特性,二進制日志格式必須設置為ROW,用於選主與write set;
- COMMIT可能會導致失敗,類似於快照事務隔離級別的失敗場景;
- 目前一個MGR集群組最多支持9個節點;
- 不支持外鍵於save point特性,無法做全局間的約束檢測與部分部分回滾;
- 二進制日志binlog不支持Replication event checksums;
- 多主模式(也就是多寫模式) 不支持SERIALIZABLE事務隔離級別;
- 多主模式不能完全支持級聯外鍵約束;
- 多主模式不支持在不同節點上對同一個數據庫對象並發執行DDL(在不同節點上對同一行並發進行RW事務,后發起的事務會失敗);
二.安裝環境
3台服務器搭建3節點MGR集群,MySQL版本5.7.28,操作系統版本CentOS 6.10。
- 192.168.109.101
- 192.168.109.102
- 192.168.109.103
2.1為了方便實驗,關閉所有節點的防火牆
[root@mysql01 ~]# service iptables stop
2.2所有節點的selinux設置為disabled
[root@mysql01 ~]# getenforce
Disabled
2.3配置各主機名和ip映射,所有節點配置一樣
[root@mysql01 ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.109.101 mysql01
192.168.109.102 mysql02
192.168.109.103 mysql03
說明:必須保證各個mysql節點的主機名不一致,並且能通過主機名找到各成員!則必須要在每個節點的
/etc/hosts
里面做主機名綁定,否則后續將節點加入group組會失敗!報錯RECOVERING!!
三.安裝步驟
3.1 官網下載5.7安裝包 mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz,建立安裝目錄/mysql和數據目錄/data/mysql,解壓壓縮包
[root@mysql01 ~]#mkdir /mysql
[root@mysql01 ~]#mkdir /data/mysql
[root@mysql01 ~]# cd /softwares/
[root@mysql01 softwares]#tar -zxvf mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz
[root@mysql01 softwares]# cd mysql-5.7.28-linux-glibc2.12-x86_64
[root@mysql01 mysql-5.7.28-linux-glibc2.12-x86_64]# cp -rf * /mysql
[root@mysql01 mysql-5.7.28-linux-glibc2.12-x86_64]#chown -R mysql.mysql /mysql /data/mysql
3.2配置環境變量
vi /root/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
#PATH=$PATH:$HOME/bin
PATH=$PATH:$HOME/bin:/mysql/bin:/mysql/lib:/mysql
export PATH
3.3配置my.cnf
mysql01配置:
[mysqld]
datadir=/data/mysql
basedir=/mysql
port=3306
socket=/data/mysql/mysql.sock
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="05153196-c2ab-43ae-b355-b9832eacf0b2"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="192.168.109.101:33061"
loose-group_replication_group_seeds="192.168.109.101:33061,192.168.109.102:33061,192.168.109.103:33061"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks= TRUE
mysql02配置:
[mysqld]
datadir=/data/mysql
basedir=/mysql
port=3306
socket=/data/mysql/mysql.sock
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="05153196-c2ab-43ae-b355-b9832eacf0b2"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="192.168.109.102:33061"
loose-group_replication_group_seeds="192.168.109.101:33061,192.168.109.102:33061,192.168.109.103:33061"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks= TRUE
mysql03配置:
[mysqld]
datadir=/data/mysql
basedir=/mysql
port=3306
socket=/data/mysql/mysql.sock
server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="05153196-c2ab-43ae-b355-b9832eacf0b2"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="192.168.109.103:33061"
loose-group_replication_group_seeds="192.168.109.101:33061,192.168.109.102:33061,192.168.109.103:33061"
loose-group_replication_bootstrap_group=off
loose-group_replication_single_primary_mode=FALSE
loose-group_replication_enforce_update_everywhere_checks= TRUE
組復制部分配置參數說明:
group_replication變量使用的loose-前綴是指示Server啟用時尚未加載復制插件也將繼續啟動 transaction_write_set_extraction = XXHASH64 ##指示Server必須為每個事務收集寫集合,並使用XXHASH64哈希算法將其編碼為散列 loose-group_replication_group_name="01e5fb97-be64-41f7-bafd-3afc7a6ab555" ##表示將加入或者創建的復制組命名為01e5fb97-be64-41f7-bafd-3afc7a6ab555 ##可自定義(通過cat /proc/sys/kernel/random/uuid) loose-group_replication_start_on_boot=off ##設置為Server啟動時不自動啟動組復制 loose-group_replication_local_address="192.168.109.101:33061" ##綁定本地的192.168.109.101及33061端口接受其他組成員的連接,IP地址必須為其他組成員可正常訪問 loose-group_replication_group_seeds="192.168.109.101:33061,192.168.109.102:33061,192.168.109.103:33061" ##本行為告訴服務器當服務器加入組時,應當連接到192.168.109.101:33061,192.168.109.102:33061,192.168.109.101:33061 ##這些種子服務器進行配置。本設置可以不是全部的組成員服務地址。 loose-group_replication_bootstrap_group = off ##配置是否自動引導組 loose-group_replication_ip_whitelist=”10.30.0.0/16,10.31.0..0/16,10.27.0.0/16″ ##配置白名單,默認情況下只允許192.168.109.x連接到復制組,如果是其他IP則需要配置。
/mysql/bin/mysqld --initialize-insecure --user=mysql --basedir=/data/mysql --datadir=/data/mysql
/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &
3.5登錄數據庫,加載MGR插件,創建同步賬號
[root@mysql01 ~]# mysql -uroot -p -S /data/mysql/mysql.sock
# 安裝MGR插件
mysql>INSTALL PLUGIN group_replication SONAME 'group_replication.so';
#設置復制賬號
mysql> SET SQL_LOG_BIN=0;
mysql> CREATE USER repl@'%' IDENTIFIED BY '123';
mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%';
mysql> FLUSH PRIVILEGES;
mysql> SET SQL_LOG_BIN=1;
mysql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='123' FOR CHANNEL 'group_replication_recovery';
四.啟動MGR單主模式
# 啟動MGR,在主庫(192.168.109.101)上執行
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
# 查看MGR組信息
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 6972ca25-25ba-11ea-b9c7-000c29dde96d | mysql01 | 3306 | ONLINE |
# 其他節點加入MGR,在從庫(192.168.109.102,192.168.109.103)上執行
mysql> START GROUP_REPLICATION;
# 查看MGR組信息
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 604a4cd6-25bb-11ea-8182-000c29378257 | mysql02 | 3306 | ONLINE |
| group_replication_applier | 6972ca25-25ba-11ea-b9c7-000c29dde96d | mysql01 | 3306 | ONLINE |
| group_replication_applier | ac6d7494-25bb-11ea-8409-000c29258d07 | mysql03 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)
可以看到,3個節點狀態為online,並且主節點為192.168.109.101,只有主節點可以寫入,其他節點只讀,MGR單主模式搭建成功。
五.切換至多主模式
MGR切換模式需要重新啟動組復制,因些需要在所有節點上先關閉組復制,設置 group_replication_single_primary_mode=OFF 等參數,再啟動組復制。
# 停止組復制(所有節點執行):
mysql> stop group_replication;
mysql> set global group_replication_single_primary_mode=OFF;
mysql> set global group_replication_enforce_update_everywhere_checks=ON;
# 隨便選擇某個節點執行
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
# 其他節點執行
mysql> START GROUP_REPLICATION;
# 查看組信息,所有節點的 MEMBER_ROLE 都為 PRIMARY
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 604a4cd6-25bb-11ea-8182-000c29378257 | mysql02 | 3306 | ONLINE |
| group_replication_applier | 6972ca25-25ba-11ea-b9c7-000c29dde96d | mysql01 | 3306 | ONLINE |
| group_replication_applier | ac6d7494-25bb-11ea-8409-000c29258d07 | mysql03 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)
可以看到所有節點狀態都是online,角色都是PRIMARY,MGR多主模式搭建成功。
六.切換回單主模式
# 所有節點執行
mysql> stop group_replication;
mysql> set global group_replication_enforce_update_everywhere_checks=OFF;
mysql> set global group_replication_single_primary_mode=ON;
# 主節點(192.168.109.101)執行
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
# 從節點(192.168.109.102、192.168.109.103)執行
START GROUP_REPLICATION;
# 查看MGR組信息
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 604a4cd6-25bb-11ea-8182-000c29378257 | mysql02 | 3306 | ONLINE |
| group_replication_applier | 6972ca25-25ba-11ea-b9c7-000c29dde96d | mysql01 | 3306 | ONLINE |
| group_replication_applier | ac6d7494-25bb-11ea-8409-000c29258d07 | mysql03 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.00 sec)
七.問題記錄
注: 前面的用戶密碼修改和創建用戶操作必須設置binlog不記錄,執行后再打開,否則會引起START GROUP_REPLICATION執行報錯:
ERROR 3092 (HY000): The server is not configured properly to be an active member of the group. Please see more details on error log.
解決方案是:根據提示打開group_replication_allow_local_disjoint_gtids_join選項,mysql命令行執行:
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
然后再執行:
mysql> start group_replication;