组复制是一种可用于实现容错系统的技术。 复制组是一个通过消息传递相互交互的 server 集群。通信层提供了原子消息(atomic message)和完全有序信息交互等保障机制。 这些是非常强大的功能,我们可以据此架构设计更高级的数据库复制解决方案。
MySQL 组复制以这些功能和架构为基础,实现了基于复制协议的多主更新。复制组由多个 server成员构成,并且组中的每个 server 成员可以独立地执行事务。但所有读写(RW)事务只有在冲突检测成功后才会提交。只读(RO)事务不需要在冲突检测,可以立即提交。换句话说,对于任何 RW 事务,提交操作并不是由始发 server 单向决定的,而是由组来决定是否提交。准确地说,在始发 server 上,当事务准备好提交时,该 server 会广播写入值(已改变的行)和对应的写入集(已更新的行的唯一标识符)。然后会为该事务建立一个全局的顺序。最终,这意味着所有 server 成员以相同的顺序接收同一组事务。因此,所有 server 成员以相同的顺序应用相同的更改,以确保组内一致。
在不同 server 上并发执行的事务可能存在冲突。 根据组复制的冲突检测机制,对两个不同的并发事务的写集合进行检测。如在不同的 server 成员执行两个更新同一行的并发事务,则会出现冲突。排在最前面的事务可以在所有 server 成员上提交,第二个事务在源 server 上回滚,并在组中的其他 server 上删除。 这就是分布式的先提交当选规则。
复制组能够以一种自动优先选择的单主模式运行,在某个时间只有一个服务器接受更新 。但是对于更高优先级的用户,组能够以多主模式部署,所有的服务器都能够接受更新,即使他们是同时发生的。
组 复制中存在着一种内建的组成员关系服务用来保持组的视图一致,并且在任意时间对于组中的所有的服务器都可用。MySQL服务器能够退出或者加入组 中,而且视图也会相应的更新。有时服务器可能会意外的退出组(故障),在这种情况下失败检测机制检测这种情况并且告知复制组视图发生了变化,这所有的一切 都是自动实现的。
组复制是一种 share-nothing 复制方案,其中每个 server 成员都有自己的完整数据副本。
MySQL 组复制协议:
在单主模式下部署组复制
组中的每个 server 实例可以在独立的物理机器上运行,也可以在同一台机器上运行。 本节介绍如何在一台物理机上创建具有三个 MySQL Server 实例的复制组。 这意味着需要三个数据目录,每个 server 实例一个,每个实例都需要单独配置。
组架构图:
第一步部署 MySQL 服务器的三个实例。
安装好MySQL服务之后首先要进行配置文件修改(三台都要,注意server-id和loose-group_replication_local_address对应每台主机),在原有配置基础上增加以下内容:
server5:(删除之前的配置)
[root@server5 ~]# cd /var/lib/mysql
[root@server5 mysql]# rm -fr *
[root@server5 mysql]# vim /etc/my.cnf
server-id=5 (三台主机Id不同即可)
gtid_mode=ON
enforce-gtid-consistency=true
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 #指示Server必须为每个事务收集写集合,并使用XXHASH64哈希算法将其编码散列.
loose-group_replication_group_name="9433c640-cace-11e8-8a9d-525400c143b6" #表示将加入或者创建的复制组命名,可以自己指定.(这里加的是server6的uuid)
loose-group_replication_start_on_boot=off #设置为Server启动时不自动启动组复制.
loose-group_replication_local_address="172.25.0.121:24901"#绑定本地的172.25.0.121以及25901端口接受其他组成员的连接,IP地址必须为其他组成员可正常访问.
loose-group_replication_group_seeds="172.25.0.121:24901,172.25.0.122:24901,172.25.0.123:24901" #本行为告诉服务器当服务器加入组时,应当连接到这些IP种子服务器进行配置。本设置可以不是全部的组成员服务地址.
loose-group_replication_bootstrap_group= off #配置是否自动引导组.
loose-group_replication_single_primary_mode=FALSE #设置组自动选择一个server来处理读/写工作。这个server是主(PRIMARY),所有其他的都是从.
loose-group_replication_enforce_update_everywhere_checks=on #多主模式下为多主更新启用或禁用严格一致性检查。
loose-group_replication_ip_whitelist=""172.25.0.0/24,127.0.0.1/8""#开启白名单,认情况下只允许白名单连接到复制组如果是其他IP则需要配置。
#使用的loose-前缀是指示Server启用时尚未加载复制插件 也将继续启动
重启数据库并设置密码
[root@server5 mysql]# /etc/init.d/mysqld restart
[root@server5 mysql]# grep password /var/log/mysqld.log
[root@server5 mysql]# mysql_secure_installation
[root@server5 mysql]# mysql -u root -p
mysql> SET SQL_LOG_BIN=0; #以下操作不写入日志
mysql> grant replication slave on *.* to user@'%' identified by 'Westos+123'; #创建复制用户及密码
mysql> flush privileges;
mysql> SET SQL_LOG_BIN=1;
mysql> change master to master_user='user',master_password='Westos+123' for channel 'group_replication_recovery';
#这个复制跟普通的change master命令有区别,并不需要指定master是谁,但需要指定通道为’group_replication_recovery’。
mysql> install plugin group_replication soname 'group_replication.so';#安装组复制插件
mysql> show plugins;
mysql> set global group_replication_bootstrap_group=ON;
mysql> start group_replication;
mysql> set global group_replication_bootstrap_group=OFF;
mysql> select * from performance_schema.replication_group_members;
#此引导应仅由单个 sever 独立完成,该 server 启动组并 且只启动一次。 这就是为什么引导配置选项的值不保存在配置文件中的原因。 如果将其保 存在配置文件中,则在重新启动时,server 会自动引导具有相同名称的第二个组。 这将导致两个不同的组具有相同的名称.
server6和server7中:
修改配置文件后,重启数据库并设置密码
[root@server7 mysql]# vim /etc/my.cnf
mysql> SET SQL_LOG_BIN=0;
mysql> GRANT REPLICATION SLAVE ON *.* TO user@'%' IDENTIFIED BY 'Westos+123';
mysql>flush privileges;
mysql> reset master;
mysql> SET SQL_LOG_BIN=1;
mysql>change master to master_user='user',master_password='Westos+123' for channel 'group_replication_recovery';
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
mysql> START GROUP_REPLICATION;
mysql> SELECT * FROM performance_schema.replication_group_members;
server6中配置相同
配置过程常见的错误:
1,来源IP没有在白名单列表中,所以连接拒绝
2,没有配置同步账号跟密码,使用的是空密码进行同步。 需要为复制通道group_replication_recovery设置同步信息:CHANGE MASTER TO MASTER_USER=’mysqlsync’, MASTER_PASSWORD=’mysqlsync_password’ FOR CHANNEL ‘group_replication_recovery’;
3,删除validate_password密码验证插件。