导读
作者:多年金融行业5年+DBA,比较低调,对技术 比 较钻研。
简介
本文涉及版本MySQL8.0.20的MGR、MGR介绍、单主/多主模式、MGR监控、单主/多主切换、异常恢复、流控、性能压测、遇到的问题和MGR的限制。
想要全文pdf版本可添加微信:tian786376668(备注:求MGR运维指南)
一、目的
了解mysql8的MGR也就是组复制的特性,搭建和配置,MGR异常的处理。
二、MGR简介
MGR也就是MySQL Group Replication的简称,这是MySQL在5.7.17版本推出全新的高可用与高扩展的解决方案,MySQL组复制提供了高可用、高扩展、高可靠的MySQL集群服务。高一致性,基于原生复制及paxos协议的组复制技术,并以插件的方式提供,提供一致数据安全保证;高容错性,只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处理,并且内置了自动化脑裂防护机制;高扩展性,节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,直到新节点和其他节点保持一致,如果某节点被移除了,其他节点自动更新组信息,自动维护新的组信息;高灵活性,有单主模式和多主模式,单主模式下,会自动选主,所有更新操作都在主上进行;多主模式下,所有server都可以同时处理更新操作。
三、MGR复制的背景
MySQL5.17的版本中,MySQL提出了一种新的同步机制,称为statemachine复制,这种复制是一种分布式的基于server之间的复制,并且组中的server成员会自动根据当前的协调。
MGR复制可以分为两种,分别是单主模式复制和多主复制模式。
单主模式,组复制具有自主选主的功能,并且只有主节点可以进行DDL和DML的操作,其他节点全部是只读状态。
多主模式,所有节点都可以进行DDL和DML操作。
对于这两种模式,MySQL都有专门的监控视图,并且有防脑裂的措施和算法,这些全靠MySQL官方推出的Paxos算法来实现。
四、MGR复制和传统复制的对比
在说MGR的复制之前我们再了解下mysql的传统复制,mysql的传统复制分为异步复制和半同步两种。
4.1. 主从复制
主从复制是异步复制
主库提交一个事务,写入binlog中,然后将它们(异步地)发送到从节点,以重新执行(在基于语句的复制中)或应用(在基于行的复制中)。这是一个shared-nothing的系统,默认情况下所有server成员都有一个完整的数据副本。
4.2. 半同步复制
半同步复制比简单的主从复制的有点在于他同样使用binlog,但是当从库收到并产生relaylog后会向主库发送一个AcK的信息包,当主库获得这个包后,认为从库已经获得relaylog,那么会继续往从库发送binlog,如果在规定参数的时间内没有接收到ACK包,那么就会降级为异步复制模式。
4.3. 组复制
组复制脱离了传统的主从模式结构,是一个具有容错功能的集群架构,在组复制的架构中,有多个server成员构成,并且每个成员都可以独立执行事务,也就意味着多写的功能,但是所有的读写事务必须在冲突校验完成后才能提交,如果是只读型的事务那么会直接提交。当某个节点上发出一个读写的事务准备提交时,那么这个节点就会向整个集群开始广播这次读写的变更和对应的一个校验标识符,然后会针对这个事务产生一个全局的顺序号,由于是有顺序号的,所以集群中的每个成员都会按照顺序去执行事务的变更从而保证了数据的一致性。
如果在不同的server上执行了相同的操作,并且产生了事务冲突,那么校验机制就会做成相应的判断,通常先提交的事务先执行,后提交的回滚。
所以从某种程度上来说,组复制是一种伪同步复制模式
所以,基于主复制的特性可以看出以下的场景往往比较适合组复制
云场景的复制,在云中往往需要动态的添加或者删除主从,那么就可以用到主复制来动态的添加或者删除。
高可用分片场景。在目前的mysql场景中高可用分片通常采用中间件的方式进行分片,但是中间件往往限制很多,如果采用主复制那么可以按照不同的分片进行写入实现分片场景。
多活模式架构。Mysql在5.7之前的弊端往往是没有oracle的多活写入模式。到了mysql8的版本组复制有了很大的提升,如果采用了主复制,那么可以采用主复制的多主模式,直接可以多点写入,实现多活。
五、组复制的详细信息
主复制的详细信息大致包含3个方面的内容,分别是主复制的传输故障检测机制、组成员关系和容错机
1.组复制的传输故障检测
组复制的传输还是采用了mysql的binlog作为日志,但是因为有排队的机制所以必须采用GTID的模式,也就是说GTID必须打开。那么当在整个MGR集群运行工作中,提交了一个读写事务,如果有某个server未响应,那么就会在集群内的所有成员进行仲裁投票,将这个未响应的活着已经死掉的server踢出集群。
2.组复制间成员关系
MGR通过专门的插件来维护组内的关系,这个插件定义了哪些server在线状态并且是在组内的,我们可以通过相关的视图进行查询,在组内的所有的server不仅对事务的提交是达成一致的,而且所能查询到的这张维护组复制的视图的内容也是一致的,如果有新的server加入到集群组内或者有现有的server要从组内移除,那么整个视图都会进行动态的调整。
在这里需要特别注意,如果有server自愿离开组内时,首先整个组会动态重新配置,此时会触发一个投票的过程,在组内的除了离开的server开始投票,如果投票达成一致,那么组内踢出离开的server并且自动开始维护视图,如果组内无法达成一致,那么系统将不会动态变更视图,此时系统会锁定整个组防止脑裂的发生,这时就需要人工介入。
3.容错机制
MGR是根据Paxos算法来实现的,所以他具有一定的容错的数量,根据官方文档给出的公式,容忍f个故障所需的server数量(n)为n = 2×f + 1。也就是说容忍一个故障没那么必须有3个server,也就说如果要实现仲裁和容错的效果,必须有3个server构成一个集群,以下是官方给出的数据
六、单主模式和多组模式
组复制可以有单主模式和多组模式两种运行方式,单主模式,也就是单点写入,其他点默认为只读状态,多主模式也就是多点写入,所有的节点都是读写状态。
组复制默认是单主模式,并且多组模式配置的节点和单主模式配置的节点无法互通
1. 单主模式
在单主模式下,组有一个设置为读写模式的单主server。组中的所有其他成员被自动设置为只读模式(超级只读模式)。主服务器通常是用于引导组的第一个server,所有其他加入的server自动从主服务器同步并设置为只读。
在单主机模式下,将禁用在多主机模式下部署的某些检查,因为系统会强制在组中每次只有一个写入server。例如,在单主模式下允许对具有外键的表进行更改,而在多主模式下不允许。在主服务器故障时,自动选主机制选择下一个主服务器。通过按字典顺序(使用其UUID)来排序剩余的server成员并选择列表中的第一个成员来作为下一个主服务器。
如果主服务器从组中移除,则启动主节点选择程序,然后从组中的其余server成员中选择新的主节点。通过查看新视图,按照词典顺序将server的UUID进行排序并选择第一个作为主节点。选择了新的主节点后,它将自动设置为只读,其他辅助节点仍然为辅助节点,因此也是只读。
2. 多主模式
多主模式,也就是所有节点都可以写入,每个节点基本都一样。
七、组复制的搭建
组复制分为单主模式和多主模式,这里都会写出搭建的过程,但是无论是单主还是多主都需要至少3台mysql服务器来搭建。
1. 单主模式搭建
初始化mysql
首先安装mysql,这里注意mysql的版本使用为mysql官方版的8.0.20,这里为了节省时间直接采用了编译过后的包直接解压后运行,这里需要特别注意,从mysql5.7开始初始化已经没有scripts了,统一采用mysqld进行初始化操作。语句如下:
/usr/local/mysql-8.0.20/bin/mysqld--defaults-file=/home/mysql/mysql/my-8020.cnf --initialize
同步参数设置
其次需要打开GTID模式,因为主复制采用的是全局事务的序列,所以必须要打开GTID,同时还需要增加以下的配置
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
transaction_isolation = READ-COMMITTED
serverid必须保证每个节点的serverid不同
gitid_mode为on表示gitd模式打开
enforce_gtid_consistency为on表示GTID校验模式打开
master_info_repository和relay_log_info_repository设置为table模式,表示将主库信息和relaylog的信息记录到mysql库的表内。
binlog_checksum为none表示不检查binlog文件
log_slave_update为on表示当这台机器的节点作为slave时,同样产生binlog文件
binlog_format 格式为row
transaction_isolation这里mysql官方强烈建议为RC,否则容易发生死锁
组复制参数设置
在配置完毕常用同步的参数后,就可以配置主复制参数,在mysql8中,组复制是是可以在线添加的,这里采用配置文件添加的方式。
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="0c6d3e5f-90e2-11e6-802e-842b2b5909d6"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address="192.168.123.46:33601"
loose-group_replication_group_seeds="192.168.123.46:33601,192.168.123.47:33601,192.168.167.134:33061"
loose-group_replication_bootstrap_group=off
loose