MySQL Group Replication正是基于这些技术和概念,实现了一种多主全更新的复制协议。
简而言之,一个Replication-group就是一组节点,每个节点都可以独立执行事务,而读写事务则会在于group内的其他节点进行协调之后再commit。因此,当一个事务准备提交时,会自动在group内进行原子性的广播,告知其他节点变更了什么内容/执行了什么事务。这种原子广播的方式,使得这个事务在每一个节点上都保持着同样顺序。这意味着每一个节点都以同样的顺序,接收到了同样的事务日志,所以每一个节点以同样的顺序重演了这些事务日志,最终整个group保持了完全一致的状态。
组复制可以在两种模式下运行。
1.在单主模式下,组复制具有自动选主功能,每次只有一个 server成员接受更新。
2.在多主模式下,所有的 server 成员都可以同时接受更新。
MGR的限制
仅支持InnoDB表,并且每张表一定要有一个主键;
必须打开GTID特性,二进制日志格式必须设置为ROW;
二进制日志不支持binlog event checksum
目前一个MGR集群最多支持9个节点
事务写集合(Transaction write set extraction)必须打开。(这个目前与savepoint冲突,这也是导致mysqldump无法备份GR实例的原因
SERIALIZABLE 隔离级别不支持
并行执行DDL可能导致数据一致性等方面的错误,目前不支持在多节点同时执行同一对象的DDL
外键的级联约束操作目前的实现并不完全支持
三 主从复制限制
1.存储引擎必须为innodb
2.每个表必须提供主键
3.只支持ipv4,网络需求较高
4.一个group最多只能有9台服务器
5.不支持Replication event checksums,
6.不支持Savepoints
7.multi-primary mode部署方式不支持SERIALIZABLE事务隔离级别
8.multi-primary mode部署方式不能完全支持级联外键约束
9.multi-primary mode部署方式不支持在不同节点上对同一个数据库对象并发执行DDL
尽管数据库服务可用,但当有一个 server 崩溃时,连接到它的客户端必须定向或故障转移到不同的 server。这不是组复制要解决的问题。连接器,负载均衡器,路由器或其他形式的中间件更适合处理这个问题。
准备阶段:
此操作是多主模式
1、开放33061端口
# --permanent永久生效,没有此参数重启后失效
firewall-cmd --zone=public --add-port=33061/tcp --permanent
重新载入防火墙
firewall-cmd --reload
firewalld常用命令
# 启动 systemctl start firewalld
# 关闭 systemctl stop firewalld
# 查看状态 systemctl status firewalld
# 开机禁用 systemctl disable firewalld
# 开机启用 systemctl enable firewalld
# 查看所有打开的端口 firewall-cmd --zone=public --list-ports
2、三台服务器设置免密
ssh-keygen -t rsa
ssh-copy-id mgr1
ssh-copy-id mgr2
ssh-copy-id mgr3
3、三台服务器设置hosts
特别要注意一个关键点: 必须保证各个mysql节点的主机名不一致,并且能通过主机名找到各成员!
则必须要在每个节点的/etc/hosts里面做主机名绑定,否则后续将节点加入group组会失败!报错RECOVERING!
vim /etc/hosts
192.168.59.138 mgr1
192.168.59.140 mgr2
192.168.59.139 mgr3
4、关闭selinux
临时关闭:输入命令setenforce 0,重启系统后还会开启。
永久关闭:输入命令vi /etc/selinux/config,将SELINUX=enforcing改为SELINUX=disabled
一、修改配置参数(三台都修改)
mgr1
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/mysql
socket=/tmp/mysql.sock
log-error=/data/mysql/mysql.err
pid-file=/data/mysql/mysql.pid
character-set-server=utf8
innodb_rollback_on_timeout = ON
collation-server=utf8_general_ci
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
lower_case_table_names=1
max_connections=10000
sync_binlog=1
binlog_format=row
########basic settings########
server-id =138
character_set_server=utf8
max_allowed_packet = 16M
lower_case_table_names=1
slow_query_log=1
slow_query_log_file=/data/mysql/slow.log
########replication settings########
#####replication 复制配置###############
log-bin = /data/mysql/mysql-bin
max_binlog_size=500M
binlog_format = row
sync_binlog=1
expire_logs_days=15
###group replication###########
gtid_mode=on
enforce_gtid_consistency= ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
#log_slave_updates是将从服务器从主服务器收到的更新记入到从服务器自己的二进制日志文件中。
transaction_write_set_extraction = XXHASH64
##server必须为每个事物收集写集合,使用XXHASH64哈希算法将其编码为散列
loose-group_replication_group_name ='51837954-2d8a-11ed-bc2d-000c29f511b3'
#组的名字可以随便起,但不能用主机的GTID
loose-group_replication_start_on_boot = off # #插件在server启动时不自动启动组复制
loose-group_replication_bootstrap_group = off #同上
loose-group_replication_ip_whitelist="192.168.59.138,192.168.59.140,192.168.59.139"
report_host=192.168.59.138
report_port=3306
loose-group_replication_local_address = '192.168.59.138:33061'
loose-group_replication_group_seeds ='192.168.59.138:33061,192.168.59.140:33061,192.168.59.139:33061'
loose-group_replication_single_primary_mode = FALSE #关闭单主模式的参数
loose-group_replication_enforce_update_everywhere_checks = TRUE #开启多主模式的参数
########innodb settings########
innodb_flush_log_at_trx_commit = 1 #改为1 是为了更安全, 值为2是性能
innodb_buffer_pool_size=128M
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
secure_file_priv="/tmp"
[mysql]
socket=/tmp/mysql.sock
default-character-set=utf8
[client]
mgr2
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/mysql
socket=/tmp/mysql.sock
log-error=/data/mysql/mysql.err
pid-file=/data/mysql/mysql.pid
character-set-server=utf8
innodb_rollback_on_timeout = ON
collation-server=utf8_general_ci
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
lower_case_table_names=1
max_connections=10000
binlog_format=row
########basic settings########
server-id =140
character_set_server=utf8
max_allowed_packet = 16M
lower_case_table_names=1
slow_query_log=1
slow_query_log_file=/data/mysql/slow.log
########replication settings########
#####replication 复制配置###############
log-bin = /data/mysql/mysql-bin
max_binlog_size=500M
binlog_format = row
sync_binlog=1
expire_logs_days=15
###group replication###########
gtid_mode=on
enforce_gtid_consistency= ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
#log_slave_updates是将从服务器从主服务器收到的更新记入到从服务器自己的二进制日志文件中。
transaction_write_set_extraction = XXHASH64
##server必须为每个事物收集写集合,使用XXHASH64哈希算法将其编码为散列
loose-group_replication_group_name ='51837954-2d8a-11ed-bc2d-000c29f511b3'
#组的名字可以随便起,但不能用主机的GTID
loose-group_replication_start_on_boot = off # #插件在server启动时不自动启动组复制
loose-group_replication_bootstrap_group = off #同上
loose-group_replication_ip_whitelist="192.168.59.138,192.168.59.140,192.168.59.139"
report_host=192.168.59.140
report_port=3306
loose-group_replication_local_address = '192.168.59.140:33061'
loose-group_replication_group_seeds ='192.168.59.140:33061,192.168.59.138:33061,192.168.59.139:33061'
loose-group_replication_single_primary_mode = FALSE #关闭单主模式的参数
loose-group_replication_enforce_update_everywhere_checks = TRUE #开启多主模式的参数
########innodb settings########
innodb_flush_log_at_trx_commit = 1 #改为1 是为了更安全, 值为2是性能
innodb_buffer_pool_size=128M
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
secure_file_priv="/tmp"
[mysql]
socket=/tmp/mysql.sock
default-character-set=utf8
[client]
mgr3
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/mysql
socket=/tmp/mysql.sock
log-error=/data/mysql/mysql.err
pid-file=/data/mysql/mysql.pid
character-set-server=utf8
innodb_rollback_on_timeout = ON
collation-server=utf8_general_ci
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
lower_case_table_names=1
max_connections=10000
sync_binlog=1
binlog_format=row
########basic settings########
server-id =139
character_set_server=utf8
max_allowed_packet = 16M
lower_case_table_names=1
slow_query_log=1
slow_query_log_file=/data/mysql/slow.log
########replication settings########
#####replication 复制配置###############
log-bin = /data/mysql/mysql-bin
max_binlog_size=500M
binlog_format = row
sync_binlog=1
expire_logs_days=15
###group replication###########
gtid_mode=on
enforce_gtid_consistency= ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
#log_slave_updates是将从服务器从主服务器收到的更新记入到从服务器自己的二进制日志文件中。
transaction_write_set_extraction = XXHASH64
##server必须为每个事物收集写集合,使用XXHASH64哈希算法将其编码为散列
loose-group_replication_group_name ='51837954-2d8a-11ed-bc2d-000c29f511b3'
#组的名字可以随便起,但不能用主机的GTID
loose-group_replication_start_on_boot = off # #插件在server启动时不自动启动组复制
loose-group_replication_bootstrap_group = off #同上
loose-group_replication_ip_whitelist="192.168.59.138,192.168.59.140,192.168.59.139"
report_host=192.168.59.139
report_port=3306
loose-group_replication_local_address = '192.168.59.139:33061'
loose-group_replication_group_seeds ='192.168.59.138:33061,192.168.59.140:33061,192.168.59.139:33061'
loose-group_replication_single_primary_mode = FALSE #关闭单主模式的参数
loose-group_replication_enforce_update_everywhere_checks = TRUE #开启多主模式的参数
########innodb settings########
innodb_flush_log_at_trx_commit = 1 #改为1 是为了更安全, 值为2是性能
innodb_buffer_pool_size=128M
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
secure_file_priv="/tmp"
[mysql]
socket=/tmp/mysql.sock
default-character-set=utf8
[client]
二、在node0和node1和node2 创建复制账号
set sql_log_bin=0;
create user rpl_user@'%';
grant replication slave on *.* to rpl_user@'%' identified by 'rpl_pass';
flush privileges;
set sql_log_bin=1;
修改账号密码,也要set sql_log_bin=0
/usr/local/mysql/bin/mysql -uroot -p123@abc
change master to master_user='rpl_user',master_password='rpl_pass' for channel 'group_replication_recovery';
组内每台主机,都需要先安装组复制插件.否则会导致启动失败.
mysql>INSTALL PLUGIN group_replication SONAME 'group_replication.so';
克隆的机器需要修改uuid,因为复制的机器uuid相同
配置完,重启mysql服务
node0节点上执行 启动组复制
set global group_replication_bootstrap_group=ON;
set global group_replication_ip_whitelist="192.168.59.0/24";
START GROUP_REPLICATION;
SELECT * FROM performance_schema.replication_group_members;
SET GLOBAL group_replication_bootstrap_group=OFF;
node1
set global group_replication_allow_local_disjoint_gtids_join=ON;
set global group_replication_ip_whitelist="192.168.59.0/24";
START GROUP_REPLICATION;
SELECT * FROM performance_schema.replication_group_members;
node2
set global group_replication_allow_local_disjoint_gtids_join=ON;
set global group_replication_ip_whitelist="192.168.59.0/24";
START GROUP_REPLICATION;
SELECT * FROM performance_schema.replication_group_members;
select * from performance_schema.replication_group_members;
查看集群状态,都为ONLINE就表示OK:
测试:
node0上创建测试库
create database mgr1;
use mgr1;
create table mgr1.t1(id int primary key, cn varchar(30));
insert into t1 values(1,'a');
node1上查看
use mgr1;
select * from t1;
node1上插入 insert into t1 values(2,'Tom');
node2上查看
node2上插入 insert into t1 values(3,'li');
模拟节点宕机
node1上,service mysql stop
node2上,继续插入数据
启动node1节点
service mysql start
mysql>
set global group_replication_allow_local_disjoint_gtids_join = on;
START GROUP_REPLICATION;
再次查看组成员,发现已重新加入组
mysql> SELECT * FROM performance_schema.replication_group_members;
注意:前面的用户密码修改和创建用户操作必须设置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;
2、连不上master,报错信息如下:
2017-04-17T16:18:14.756191+08:00 25 [Warning] Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information.
2017-04-17T16:18:14.814193+08:00 25 [ERROR] Slave I/O for channel 'group_replication_recovery': error connecting to master'repl_user@host-192-168-99-156:3306' - retry-time: 60 retries: 1, Error_code: 2005
2017-04-17T16:18:14.814219+08:00 25 [Note] Slave I/O thread for channel 'group_replication_recovery' killed while connecting to master
2017-04-17T16:18:14.814227+08:00 25 [Note] Slave I/O thread exiting for channel 'group_replication_recovery', read up to log 'FIRST', position 4
2017-04-17T16:18:14.814342+08:00 19 [ERROR] Plugin group_replication reported: 'There was an error when connecting to the donor server. Check group replication recovery's connection credentials.'
解决方案:
添加映射
vim /etc/hosts
重启下组复制
mysql> stop group_replication;
Query OK, 0 rows affected (8.76 sec)
mysql> start group_replication;
Query OK, 0 rows affected (2.51 sec)
日常维护步骤:
1、如果从库某一节点关闭
stop group_replication;
2、如果所有的库都关闭后,第一个库作为主库首先执行
set global group_replication_bootstrap_group=ON;
start group_replication;
剩下的库直接执行即可!
set global group_replication_allow_local_disjoint_gtids_join=ON;
start group_replication;
3、如果主库故障,会自动从两个从库选出一个主库,主库启动后再次执行如下命令后会变成从库
start group_replication;
至此MGR搭建并验证完成