组复制模型:
MySQL组复制是MySQL 5.7.17开始引入的新功能,为主从复制实现高可用功能 它支持单主模型和多主模型两种工作方式(默认是单主模型)
单主模型:从复制组中众多个MySQL节点中自动选举一个master节点,只有master节点可以写,其他节点自动设置为read only 当master节点故障时,会自动选举一个新的master节点,选举成功后,它将设置为可写,其他slave将指向这个新的master
多主模型:复制组中的任何一个节点都可以写,因此没有master和slave的概念 只要突然故障的节点数量不太多,这个多主模型就能继续可用
组复制原理:
复制组由多个 server成员构成,并且组中的每个 server 成员可以独立地执行事务 但所有读写(RW)事务只有在冲突检测成功后才会提交。只读(RO)事务不需要在冲突检测,可以立即提交。换句话说,对于任何 RW 事务,提交操作并不是由始发 server 单向决定的,而是由组来决定是否提交。准确地说,在始发 server 上,当事务准备好提交时,该 server会广播写入值(已改变的行)和对应的写入集(已更新的行的唯一标识符)。然后会为该事务建立一个全局的顺序。最终,这意味着所有 server成员以相同的顺序接收同一组事务。因此,所有 server 成员以相同的顺序应用相同的更改,以确保组内一致。
组复制能够根据在一组 server 中复制系统的状态来创建具有冗余的容错系统。因此,只要它不是全部或多数 server 发生故障,即使有一些 server 故障,系统仍然可用,最多只是性能和可伸缩性降低,但它仍然可用。server 故障是孤立并且独立的。它们由组成员服务来监控,组成员服务依赖于分布式故障检测系统,其能够在任何 server 自愿地或由于意外停止而离开组时发出信号。
总之,MySQL 组复制提供了高可用性,高弹性,可靠的 MySQL 服务 但是组复制的效率很低 当master节点写数据的时候,会等待所有的slave节点完成数据的复制,然后才继续往下进行 组复制的每一个节点都可能是slave
续上篇博客
server3先杀死proxy进程
组复制(全同步复制),互相主从,互相为master和slave 就相当于一个集群,都可以作为master和slave 只需要在一个上面开启组复制即可,大家都是master
server1(master)节点: 1.关闭mysqld systemctl stop mysqld 并复制一个uuid作为组复制的uuid,因为组复制中的uuid不能是其中成员的uuid,必须是除此之外的 2.删除mysql数据 ##注意 :删除数据之前先复制uuid /var/lib/mysql/auto.cnf rm -fr /var/lib/mysql/*复制一个uuid作为组复制的uuid 物理机 将uuid先保存在一个文件里面 3.修改配置文件 ##官网 https://dev.mysql.com/doc/refman/5.7/en/group-replication-configuring-instances.html
vim /etc/my.cnf log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid server_id=1 gtid_mode=ON enforce_gtid_consistency=ON master_info_repository=TABLE relay_log_info_repository=TABLE binlog_checksum=NONE #关闭binlog校验 log_slave_updates=ON log_bin=binlog binlog_format=ROW #组复制依赖基于行的复制格式 transaction_write_set_extraction=XXHASH64 loose-group_replication_group_name="c36cc649-3f17-11e9-960e-525400cf2a01" ##可以看/var/lib/mysql/auto.cnf loose-group_replication_start_on_boot=off loose-group_replication_local_address= "172.25.136.1:24901" loose-group_replication_group_seeds= "172.25.136.1:24901,172.25.136.2:24901,172.25.136.3:24901" loose-group_replication_bootstrap_group=off ##插件是否自动引导,这个选项一般都要off掉,只需要由发起组复制的节点开启,并只启动一次,如果是on,下次再启动时,会生成一个同名的组,可能会发生脑裂 loose-group_replication_ip_whitelist="127.0.0.1,172.25.136.0/24" loose-group_replication_enforce_update_everywhere_checks=ON loose-group_replication_single_primary_mode=OFF #后两行是开启多主模式的参数 4.启动mysqld systemctl start mysqld 5.初始化数据库 [root@server1 mysql]# grep password /var/log/mysqld.log 2019-03-14T07:50:42.947487Z 1 [Note] A temporary password is generated for root@localhost: J)hjM=V39sw> 登录数据库,先修改密码 mysql> alter user root@localhost identified by 'Wsp+123ld'; 6.配置 #看官网复制 https://dev.mysql.com/doc/refman/5.7/en/group-replication-user-credentials.html mysql> SET SQL_LOG_BIN=0; #关闭二进制日志,防止传到其他server上 mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Wsp+123ld'; ##创建用户 mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; ##用户授权 mysql> FLUSH PRIVILEGES; 刷新用户授权表 mysql> SET SQL_LOG_BIN=1; ##开启日志 mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Wsp+123ld' FOR CHANNEL 'group_replication_recovery'; 配置用户 mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so'; 安装组复制插件 mysql> SHOW PLUGINS; ##查看插件 | group_replication | ACTIVE | GROUP REPLICATION | group_replication.so | GPL | +----------------------------+----------+--------------------+----------------------+---------+ 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; ##查看server1是否online,查看组的状态,当前只有一个节点在线 ###注意:先不要添加数据 最后测试的时候再添加 加入数据 mysql> CREATE DATABASE test; mysql> USE test; mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL); 创建表 mysql> INSERT INTO t1 VALUES (1, 'Luis'); 插入数据 mysql> SELECT * FROM t1; 查看表##添加server2到组内 server2上: [root@server2 mysql]# systemctl stop mysqld rm -fr /var/lib/mysql/* vim /etc/my.cnf 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="c36cc649-3f17-11e9-960e-525400cf2a01" ##注意:这里和server1的保持一致!!!!!! loose-group_replication_start_on_boot=off loose-group_replication_local_address= "172.25.136.2:24901" loose-group_replication_group_seeds= "172.25.136.1:24901,172.25.136.2:24901,172.25.136.3:24901" loose-group_replication_bootstrap_group=off loose-group_replication_ip_whitelist="127.0.0.1,172.25.136.0/24" loose-group_replication_enforce_update_everywhere_checks=ON loose-group_replication_single_primary_mode=OFF #启动mysqld systemctl start mysqld 假如你在重启服务时出现报错,有可能手残把配置文件写错了 找到错误后先执行一次关闭服务操作,然后删除mysql数据目录下的所有内容,再次尝试打开服务 #初始化 grep password /var/log/mysqld.log #进入数据库 mysql> alter user root@localhost identified by 'Wsp+123ld'; #修改root用户密码 mysql> SET SQL_LOG_BIN=0; mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Wsp+123ld'; mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%'; mysql> FLUSH PRIVILEGES; mysql> SET SQL_LOG_BIN=1; mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Westos+001' FOR CHANNEL 'group_replication_recovery'; mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so'; SHOW PLUGINS; #这里不需要做server1上做的SET GLOBAL group_replication_bootstrap_group=ON; mysql> START GROUP_REPLICATION; '这里开启组复制可能会报错,查看mysql日志' 开启组复制,报错,因为节点1已经写入数据,两端数据不一致 'cat /var/log/mysqld.log ,找到解决办法' 2019-03-14T08:51:52.838185Z 0 [Note] Plugin group_replication reported: 'To force this member into the group you can use the group_replication_allow_local_disjoint_gtids_join option' set global group_replication_allow_local_disjoint_gtids_join=on; mysql -pWsp+123ld mysql> STOP GROUP_REPLICATION; mysql> set global group_replication_allow_local_disjoint_gtids_join=on; ##直接做这一步 不用等报错 mysql> START GROUP_REPLICATION; 恢复正常
从server1上也可以看到两台服务器已经加入到了组复制的集群中。
#再配置server3,和server2配置相同 配置好后在server1上查看 mysql> SELECT * FROM performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ | group_replication_applier | 43a9e177-46c2-11e9-9b8a-52540039a8e5 | server3 | 3306 | ONLINE | | group_replication_applier | 926e543f-4635-11e9-bb87-525400cf2a01 | server2 | 3306 | ONLINE | | group_replication_applier | de5a155a-462d-11e9-b9df-5254004c61ed | server1 | 3306 | ONLINE | +---------------------------+--------------------------------------+-------------+-------------+--------------+ 看到3台都是online,表示正常 这时在任何一个节点都可以看到刚才插入的数据 在任何节点写入数据,其他节点也能看到 如在server3上: mysql> INSERT INTO t1 VALUES (2, 'wsp'); 在server2和server1上查看: mysql> select * from t1; +----+------+ | c1 | c2 | +----+------+ | 1 | Luis | | 2 | wsp | +----+------+ 可以看到刚插入的数据在server1和server2查看数据 可以看到,已经实现了组复制,可以在任意一个节点写数据,其他两个节点会进行组复制。
