MGR架构~原理细节分析(8.0最新版)
零 总揽
1 写集合 2 冲突验证机制 3 监控 4 大事务影响 5 流控设置 6 网络抖动影响 7 新节点的初始化加入机制
一 新主选择机制
1 当主节点宕掉,自动会根据服务器的server_uuid变量和group_replication_member_weight变量值,选择下一个slave谁作为主节点,group_replication_member_weight的值最高的成员被选为新的主节点,
2 在group_replication_member_weight值相同的情况下,group根据数据字典中 server_uuid排序,排序在最前的被选择为主节点
3 如果原主需要下线进行维护,那么可以直接stop复制,如果有目标新主,预先调整好权重即可.新主会进行识别
二 集群节点数量
1 一旦集群故障的节点超过阈值,整个集群变会被挂起,成为只读的状态,比如 3个节点,一旦挂掉2个 就会导致集群只读
计算方式 2n+1=total, n为故障节点的阈值
三 集群节点状态
ONLINE 表示该节点可正常提供服务
RECOVERING 表示当前节点正在从其他节点恢复数据(也有可能处于错误状态)
OFFLINE 表示GR插件已经加载,但是该节点不属于任何一个GR组
ERROR 表示节点在recovery阶段或者从其他节点同步状态中出现错误
UNREACHABLE 表示节点处于不可达状态,无法与之发生网络通讯
只有ONLINE和RECOVERING两种状态会在集群中得到同步
四 集群节点延时
组复制的延迟对集群是有影响的,一旦出现延迟(默认延迟25000个事务),则启动流量控制(Flow Control),每个周期性能衰减当前的10%,直到集群不可用(但集群节点状态为online),单个节点慢整个集群全慢。
五 写集合
关于wriset你需要知道的几个事情
1 writeset本身是由vector和set集合基本单位(c++)的集合,内部都是hash成员
2 事务语句生成所有writeset内部成员,然后由这些成员构成writeset集合
3 事务整体的wrieset大概包含以下,然后内部进行hash
1 主键的信息和值 2 库表的信息 3 辅助索引的信息和值
4 writeset的生成是在binlog刷到os disk之前,writeset+binlog cache+server_uuid+gtid_executed等其他信息, 发送到各个节点进行冲突验证
5 对于 5.7来说,每个唯一键都会生成一个Writeset
6 但是如果是大事物上千万的表在一个事物里面做修改那么内存可能消耗会上百兆,这也是为什么MGR需要避免大事务的原因之一,哪怕生成大量的writeset也是占用内存的,更不用说发送验证和应用了
六 整体过程
0 MGR 在主节点执行事务,形成集合(包含写集合,binlog event和其他一些信息)并且按照顺序广播发送到各个成员
1 从节点进行冲突验证,验证通过后
2 主节点进行binlog写入提交,反馈给客户端
3 从节点写入relay-log,然后进入应用队列
4 由注册的复制通道group_replication_applier channel完成事务并行回放。
七 大事务对MGR本身的影响
1 在生成阶段,大事务本身在主节点执行就很久,影响的行数非常多,就会生成大量的writeset和binlog,writeset和binlog都会占用服务器的本身资源
2 在传输阶段,这样很明显会影响节点之前的网络传输性,比如造成网络抖动,可能造成节点脱离的风险
3 在事务冲突验证阶段: 也同样会消耗节点的大量资源
4 在事务应用阶段,1 消耗节点的资源 2 可能造成后续的事务无法应用,造成延时,拖慢整个集群的性能
参数限制:MGR能对生成binlog大于多少的事务进行限制,直接拒掉,建议采用设置
最后建议: 请不要使用大事务
八 MGR事务检测机制-冲突检测数据库
1 冲突检测数据库=>hash_map
key:是数据库名+表名+主键id经过哈希后的字符串
value:Gtid_set_ref对象(是gtid_set的超集),包含了主键版本信息(表示为更新了该主键id的最后一个事务执行完后的系统gtid_executed)
4 当启用检测模式时,只有事务的snapshot_version不是冲突检测数据库中对应主键版本的子集时,事务才能够判定为认证通过(多写/主从切换)
九 冲突检测数据库的问题
0 冲突检测数据库=>hash_map,冲突检测数据库的作用有2个 1是验证是否冲突,决定事务提交还是回滚 2 为认证通过的事务分配gtid,决定事务的并行回放行为,含有seq_number,只有通过冲突检测和并行回放过的事务才能被清理
1 如果一个事务在各个节点都已经执行或回放了,那么该事务的writeset信息就不需要继续缓存在冲突检测数据库中。MGR会对其进行周期性清理(1分钟一次)。先广播各自节点的gtid_executed信息,然后收集其他节点的gtid_executed信息取交集stable_gtid_set,再基于这个交集来清理无用的信息
2 在某些较极端的情况下,比如流控参数设置较大,或每个事务writeset较多,或gtid_set较大时。writeset清理不及时也容易导致冲突检测数据库占据过多内存空间,导致mysqld OOM
3 不仅仅多主模式,在单主模式的新主切换过程中,也需要进行事务认证,应用冲突检测数据库
4 每个事务进行认证的时候都会携带执行该事务时节点的gtid_executed,也就是事务的版本snapshot_version,以及事务所修改的记录信息writeset。通过这两部分信息跟冲突检测数据库里的信息进行比对,就能确定该事务应该提交还是回滚
十 关于集群的补充
1 当 group_replication_bootstrap_group被显式设为ON时 start group_replication执行的操作是创建一个新的集群,而当group_replication_bootstrap_group被显式设为OFF时,group_replication是加入已有的集群,所以我们在新创建的集群时初始化主必须显示设置新集群,而在从节点加入时,直接执行即可.所有节点在配置文件中group_replication_bootstrap_group被设置为OFF
2 监控项重点
1 全局性视图 replication_group_members
2 replication_connection_status
1 CHANNEL_NAME: group_replication_applier 获取应用进程,重点是接收到的所有事务GTID
2 CHANNEL_NAME: group_replication_recovery 此通道监控恢复进程
3 监控要点
1 集群角色是否正常 ( status是否为online role是否为read_only)
2 延时监控(已经执行过的gtid集合对比收到的gtid集合相差则为延时)
3 一个健康的集群所有的GTID集合应该是一致的,在0延时的情况
十一 新节点什么情况下会发生加入失败情况
1 新节点本身已有自身事务,日志会有相应提示
This member has more executed transactions than those present in the group.而同步的时候会携带已执行的GTID_EXECUTED集合,通过本地新节点的GTID_EXECUTED对比发现并不在集合里,故而报错
2 新节点网段并不在iplist规定的网段内
3 新节点需要的全量日志在主库已被删除,recovery通道会报错 日志会有相应提示 GET ERROR 12306
4 当原主切换后,重新加入集群的操作
1 分别设置 read_only super_read_only 为ON 2 重新加入集群 3 观察状态和数据同步
十二 高可用集群
1 软件 https://github.com/gaopengcarl/HAIPMGR
2 运行环境: 每个节点都需要进行启动该脚本,因为该软件只会检测本地IP
3 相关原理: 1 检测VIP 2 检测mysql进程 3 检测 online 和 read_only
4 经测试能正常切换,推荐使用这个代替proxysql,proxysql本身是有性能损耗的