mysql5.7—基于GTID的半同步复制

扩展

前面我们已经了解并配置过了mysql5.7的主从复制与基于GTID的主从复制,今天我们再来认识一种MYSQL的复制—半同步复制,又是一种复制,MYSQL到底有多少种复制呢?我们先来看看MySQL的复制架构衍生史。 MySQL的复制分为四种:

1: 普通的replication,异步同步。 搭建简单,使用非常广泛,从mysql诞生之初,就产生了这种架构,性能非常好,可谓非常成熟。 但是这种架构数据是异步的,所以有丢失数据库的风险。
2: semi-sync replication,半同步。性能,功能都介于异步和全同步中间。从mysql5.5开始诞生,目的是为了折中上述两种架构的性能以及优缺点。
3: sync replication,全同步。目前官方5.7基于Group replication的全同步技术处在labs版本,离正式集成已经不远。全同步技术带来了更多的数据一致性保障。相信是未来同步技术一个重要方向,值得期待。
4: mysql cluster。 基于NDB引擎,搭建也简单,本身也比较稳定,是mysql里面对数据保护最靠谱的架构,也是目前唯一一个数据完全同步的架构,数据零丢失。不过对业务比较挑剔,限制也较多。

半同步复制

我们今天就来看看这第二种架构—半同步复制,我们知道,普通的replication,即mysql的异步复制,依靠mysql二进制日志也即binary log进行数据复制。比如两台机器,一台主机(master),另外一台是从机(slave)。
1: 正常的复制为:事务一(t1)写入binlog buffer;dumper 线程通知slave有新的事务t1;binlog buffer 进行checkpoint;slave的io线程接收到t1并写入到自己的的relay log;slave的sql线程写入到本地数据库。 这时,master和slave都能看到这条新的事务,即使master挂了,slave可以提升为新的master。
2: 异常的复制为:事务一(t1)写入binlog buffer;dumper 线程通知slave有新的事务t1;binlog buffer 进行checkpoint;slave因为网络不稳定,一直没有收到t1;master 挂掉,slave提升为新的master,t1丢失。
3: 很大的问题是:主机和从机事务更新的不同步,就算是没有网络或者其他系统的异常,当业务并发上来时,slave因为要顺序执行master批量事务,导致很大的延迟。

为了弥补以上几种场景的不足,mysql从5.5开始推出了半同步。即在master的dumper线程通知slave后,增加了一个ack,即是否成功收到t1的标志码。也就是dumper线程除了发送t1到slave,还承担了接收slave的ack工作。如果出现异常,没有收到ack,那么将自动降级为普通的复制,直到异常修复。
我们可以看到半同步带来的新问题:
1: 如果异常发生,会降级为普通的复制。 那么从机出现数据不一致的几率会减少,并不是完全消失。
2: 主机dumper线程承担的工作变多了,这样显然会降低整个数据库的性能。
3: 在MySQL 5.5和5.6使用after_commit的模式下, 即如果slave 没有收到事务,也就是还没有写入到relay log 之前,网络出现异常或者不稳定,此时刚好master挂了,系统切换到从机,两边的数据就会出现不一致。 在此情况下,slave会少一个事务的数据。

随着MySQL 5.7版本的发布,半同步复制技术升级为全新的Loss-less Semi-Synchronous Replication架构,其成熟度、数据一致性与执行效率得到显著的提升。

配置基于GTID的mysql半同步复制

实验环境

半同步复制在异步复制(我们之前搭建号的主从复制就是异步复制)的基础上进行,所以我们直接开启上次做主从复制的虚拟机进行实验,没有做的话,先搭建号mysql的主从复制再进行mysql的半同步复制

配置

一、检查mysql主从复制是否正确,检查完后关闭slave
在slave中:show slave status\G;
stop slave;
在这里插入图片描述
在这里插入图片描述
二、在master中
1:安装master插件
install plugin rpl_semi_sync_master soname ‘semisync_master.so’;
2:set global rpl_semi_sync_master_enabled=1; ##启用master的半同步复制,也可以将此选项写到配置文件/etc/my.cnf中
在这里插入图片描述
三、在slave中
1:安装slave插件
install plugin rpl_semi_sync_slave soname ‘semisync_slave.so’;
2:set global rpl_semi_sync_slave_enabled=1; ##启用slave半同步复制,可以写到配置文件中
3:重启slave上的IO线程,如果没有重启,则默认还是异步复制,重启后,slave会在master上注册为半同步复制的slave角色。
stop slave io_thread;
start slave io_thread;
在这里插入图片描述
四、在master端查看配置情况
1:查看环境变量
show variables like ‘%semi%’;
在这里插入图片描述

1:rpl_semi_sync_master_timeout
这个参数的值为10000,即10s,意为等待slave传回ack的时间,超过10s将变为异步复制
2:rpl_semi_sync_master_wait_for_slave_count
MySQL 5.7.3引入的,该变量设置主需要等待多少个slave应答,才能返回给客户端,默认为1
3:rpl_semi_sync_master_wait_no_slave
## 当这个参数的值为ON时:默认值,当状态变量Rpl_semi_sync_master_clients中的值小于
rpl_semi_sync_master_wait_for_slave_count时,Rpl_semi_sync_master_status依旧
显示为ON。
## 当这个参数的值为OFF时:当状态变量Rpl_semi_sync_master_clients中的值于rpl_semi_sync_master_wait_for_slave_count
时,Rpl_semi_sync_master_status立即显示为OFF,即异步复制。
4:rpl_semi_sync_master_wait_point
该参数有两个值:
(1):AFTER_COMMIT(5.6默认值)
master将每个事务写入binlog ,传递到slave 刷新到磁盘(relay log),同时主库提交事务。
master等待slave 反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给
客户端。
(2):AFTER_SYNC(5.7默认值,但5.6中无此模式)
master 将每个事务写入binlog , 传递到slave 刷新到磁盘(relay log)。master等待slave
 反馈接收到relay log的ack之后,再提交事务并且返回commit OK结果给客户端。 即使主库
 crash,所有在主库上已经提交的事务都能保证已经同步到slave的relay log中。
## 因此5.7引入了after_sync模式,带来的主要收益是解决after_commit导致的master crash
主从间数据不一致问题,因此在引入after_sync模式后,所有提交的数据已经都被复制,故障切换
时数据一致性将得到提升。

2:查看状态变量
show status like ‘%semi%’;
在这里插入图片描述

Rpl_semi_sync_master_clients
当前半同步复制slave的个数,如果是一主多从的架构,并不包含异步复制slave的个数。

五、在master与slave中分别查看半同步运行状态
在master中:
show status like ‘Rpl_semi_sync_master_status’;
在这里插入图片描述
在slave中:
start slave;
show status like ‘Rpl_semi_sync_slave_status’;
在这里插入图片描述
这两个变量常用来监控主从是否运行在半同步复制模式下。value为ON,
所以,MySQL半同步复制搭建成功!!
事实上,半同步复制并不是严格意义上的半同步复制,当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。

测试

一、第一次测试
1:在master中插入数据
往user库的usertb表中插入一条数据:
insert into user.usertb value (‘user2’,‘123’);
在这里插入图片描述
master的操作很快就能返回,因为很快就会收到slave传回的的ack
2:在slave中查看
select * from user.usertb;
在这里插入图片描述
二、第二次测试
1:先在slave中执行:
stop slave;
show status like ‘Rpl_semi_sync_slave_status’;
在这里插入图片描述
2:在master中
insert into user.usertb values(‘user3’,‘456’);
show status like ‘Rpl_semi_sync_master_status’;
insert操作需要10.08s才返回,而这与rpl_semi_sync_master_timeout参数的时间相吻合。
此时,两个状态的值,均为“OFF”。
在这里插入图片描述
三、第三次测试
1:开启slave,则主和从会快速恢复到半同步复制
在这里插入图片描述
2:在master中
show status like ‘Rpl_semi_sync_master_status’;
在这里插入图片描述

至此,基于GTID的mysql5.7半同步复制就配置完成了!!

猜你喜欢

转载自blog.csdn.net/gd0306/article/details/84843172