书接上文,我们接着来看主从复制。
作延迟复制时,第一是要判断延迟到达什么某种程度时,业务会受影响,第二是要考虑延迟复制时我们有没有后悔的机会,即如果我们延迟复制的延迟时间设为30min,如果我们在master端做了误操作,我们还有30min的时间来撤回误操作而不影响后面的slave端。
在slave端定义延迟(在设置前要先将SQL线程停掉,设置完成后再开启),默认单位为s:
测试:
我们在server2上设置了延迟30s,我们在master上插入数据:
server3:
server2:
可以看到我们在master上插入数据后,server3立马就同步了,但是server2还没有同步。
接下来我们来看SQL线程。由于master默认情况下时多用户多线程同时写入的,而slave端默认情况下SQL线程是单线程,这样就会造成更大的延迟,所以我们就来设置slave端的并行复制。
可以查看现在数据库中的线程:
在slave端设置 /etc/my.cnf :
设置完成后,重启mysql:
此时进到mysql数据库里,刚才设置的以表的形式记录的日志文件就在里面:
如果数据库中哪个线程比较慢,要把它查出来并显示出来。数据库可以把慢查询日志记录到文件里:
开启慢查询日志:
默认设置线程超过10s我们认为它是慢查询:
测试:
创建一个超过10s的线程:
找到慢查询日志,可以查到哪个线程超时:
组复制分单主模式和多主模式,mysql 的复制技术仅解决了数据同步的问题,如果 master 宕机,意味着数据库管理员需要介入,应用系统可能需要修改数据库连接地址或者重启才能实现。(这里也可以使用数据库中间件产品来避免应用系统数据库连接的问题,例如 mycat 和 atlas 等产品)。组复制在数据库层面上做到了,只要集群中大多数主机可用,则服务可用,也就是说3台服务器的集群,允许其中1台宕机。组复制的流程图如下:
一主多从:
多主多从:
组复制的特点:
● 高一致性
基于原生复制及 paxos 协议的组复制技术,并以插件的方式提供,提供一致数据安全保证;
● 高容错性
只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处理,并且内置了自动化脑裂防护机制;
● 高扩展性
节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,直到新节点和其他节点保持一致,如果某节点被移除了,其他节点自动更新组信息,自动维护新的组信息;
● 高灵活性
有单主模式和多主模式,单主模式下,会自动选主,所有更新操作都在主上进行;多主模式下,所有 server 都可以同时处理更新操作。
什么样的应用场景适合用组复制?
- 弹性的数据库复制环境:组复制可以灵活的增加和减少集群中的数据库实例
- 高可用的数据库环境:组复制允许数据库实例宕机,只要集群中大多数服务器可用,则整个数据库服务可用
- 替代传统主从复制结构的数据库环境
组复制的有哪些先决条件?
- 只支持innodb存储引擎
- 每张表都需要有主键
- 只支持ipv4网络环境
- 要求高网络带宽(通常是千兆内网)和低网络延迟
在进行组复制之前我们先把之前的环境清理一下。先将所有节点的mysql线程停掉,再将所有节点的mysql数据删掉。
编辑配置文件:/etc/my.cnf
- [mysqld]
- datadir=/data/mysql
- socket=/data/mysql/mysql.sock
- symbolic-links=0
-
- disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
- 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
-
- plugin_load_add='group_replication.so'
- transaction_write_set_extraction=XXHASH64
- group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
- group_replication_start_on_boot=off
- group_replication_local_address= "172.25.254.1:33061"
- group_replication_group_seeds= "172.25.254.1:33061,172.25.254.2:33061,172.25.254.3:33061"
- group_replication_bootstrap_group=off
- group_replication_ip_whitelist="172.25.254.0/24,127.0.0.1/8"
- group_replication_single_primary_mode=OFF
- group_replication_enforce_update_everywhere_checks=ON
由于刚刚我们把所有文件都删掉了,所以要重新初始化:
启动数据库后先更改密码:
- mysql> SET SQL_LOG_BIN=0; #禁止记录二进制日志(禁止下面的操作记录下来)
- mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'password';
- 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='password' FOR CHANNEL 'group_replication_recovery';
-
- mysql> SET GLOBAL group_replication_bootstrap_group=ON; #此条语句只需要在第一个启动的节点上运行即可,用于引导组复制
- mysql> START GROUP_REPLICATION;
- mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
此时开启节点,第一个节点server1已经online了:
在server2上:
若是遇到以下问题:
2022-06-28T07:57:57.413399Z 0 [ERROR] Plugin group_replication reported: 'This member has more executed transactions than those present in the group. Local transactions: 9ae1f206-f6b7-11ec-9e1f-525400c45af7:1 > Group transactions: aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1, ce3e3187-f6b3-11ec-a34d-525400bcfd41:1' 2022-06-28T07:57:57.413430Z 0 [ERROR] Plugin group_replication reported: 'The member contains transactions not present in the group. The member will now exit the group.' 2022-06-28T07:57:57.413434Z 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; 然后将此设置写进配置文件。
在server3上做同样的操作:
此时三台节点全部启动起来。接下来创建表结构,里面要包含主键:
- 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');
在server2和server3上查询,均有刚刚插入的数据:
此时我们在server3上插入数据,在server1和server2上查询均有插入的数据:
此时三个节点完全同步,这就是mysql组复制,分布式的集群。 注:主键的值是唯一的不能重复。