MySQL组复制-初见
在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是数据库学习者,那么本文《MySQL组复制-初见》就很适合你!本篇内容主要包括MySQL组复制-初见,希望对大家的知识积累有所帮助,助力实战开发!
自从MySQL组复制(Group Replication)跟随5.7.17发布以来,MySQL真正有了成熟的高可用分布式集群方案,摆脱了之前master-slave+第三方工具的伪集群。笔者将整理关于MySQL组复制的系列文章,这是第一篇,简要介绍组复制的来世今生以及相关特性,希望对大家有帮助
简介
在介绍组复制之前,让我们先回顾一下传统的master-slave复制形式,这将有利于我们理解组复制要解决什么问题

传统复制
传统的MySQL复制形式为主从复制,由一个主库(master)和一个或多个从库(slave)组成。事务只能在主库执行,主库执行事务,提交(commit)之后,将会传播给从库执行。一般这个过程是异步的,由binlog提供基于语句的复制(实际执行的sql),或者基于行的复制(增删改的行sql)。这是一个shared-nothing的系统,所有主从都有一套完整独立的数据。
由于纯异步复制可能会造成数据丢失(以后详细分析),5.5中以插件形式引入了半同步复制,在主库向客户端返回事务已提交的信号之前,多了一个同步步骤,要等从库通知主库事务已接收。这个同步可以发生在server层sync binlog之后、innodb引擎commit之前(after sync),或者在innodb引擎commit之后、返回给客户端之前(after commit)。
组复制
组复制是一种可以用来实现高可用集群的技术,组内的各个服务器相互通信协作,来保证事务的ACID特性。组复制实现了多主写入的特性,即,任意一个主库都可以做数据的更新,事务会被复制到其余的主库以及从库中。在被写入的主库返回给客户端事务已提交之前,组复制插件会保证将被写入的数据,以及写集(write set,写入数据的唯一标识符,一般为主键)有序传播到其他的主库中。注意,这个“有序”非常重要,它将保证所有主库接收到的都是一致的事务,而不至于发生数据错乱。
显而易见的是,多主写入的特性下,多个客户端并发更新数据,必然导致事务冲突,如何解决冲突就显得尤为重要。这个时候,写集(write set)的作用就体现出来了,如果在不同主库上的两个事务,更新了同一行数据,它们将产生相同的写集,MySQL就能检测到事务冲突。MySQL解决冲突的策略是,谁先提交以谁为主,后提交的事务回滚,这样来保证数据的一致性。
和传统复制一样,组复制也是一个shared-nothing的系统,所有主库都有同等的完整数据。
组复制不解决数据分片问题。
组复制细节
组复制整个逻辑是实现在MySQL插件里的,作为传统过复制框架的一种扩展,基于binlog、GTID,和一个第三方的组内通讯组件Corosync by corosync实现。除此之外,组复制还实现了动态变更机制,新机器可以动态加入一个一存在的组复制集内。
组:复制的基本单位
在组复制中,相互复制的几组服务器组成了一个基本单位:组(group)。一个组用uuid作为组名,新的服务器可以自动加入到一个组中,以传统的复制方式复制数据,从而和现有服务器的数据保持一致,无需人工干预。
当一个服务器从组中下线时,其他服务器会自动感知这个下线事件,并作出相应调整
多点写入
由于不存在传统意义上的主库,组中的任意一个节点都可以用来执行事务,包括写入类事务。就像前面提到过的,在事务提交前,要做一些额外的检查工作:
- 检查事务是否有冲突
- 将事务传播给其他节点,其他节点需要确认已接收到事务
解决冲突的时候,组复制遵循先到先的的原则。例如,t1/t2两个事务,逻辑上t1先提交,然而在t2的节点上,t2被先执行(本地事务)。当t1事务被广播到t2后,t2所在的节点检测到两个事务写集(write set)冲突,并且t1先提交。那么根据原则,t2所在的节点将回滚t2事务,执行t1。
实践中,如果频繁发生本地事务被远程事务回滚,那么建议将两个事务放同一个节点执行,由本地的锁管理器控制并发问题,而不是等事务传播过来之后,再解决冲突。
监控
和其他指标一样,组复制的监控数据可以从
member1> SELECT * FROM performance_schema.replication_group_members\G *************************** 1. row *************************** CHANNEL_NAME: group_replication_applier MEMBER_ID: 597dbb72-3e2c-11e4-9d9d-ecf4bb227f3b MEMBER_HOST: nightfury MEMBER_PORT: 13000 MEMBER_STATE: ONLINE *************************** 2. row *************************** CHANNEL_NAME: group_replication_applier MEMBER_ID: 59efb8a1-3e2c-11e4-9d9d-ecf4bb227f3b MEMBER_HOST: nightfury MEMBER_PORT: 13001 MEMBER_STATE: ONLINE *************************** 3. row *************************** CHANNEL_NAME: group_replication_applier MEMBER_ID: 5a706f6b-3e2c-11e4-9d9d-ecf4bb227f3b MEMBER_HOST: nightfury MEMBER_PORT: 13002 MEMBER_STATE: RECOVERING
事务信息(等待执行、事务冲突等)
member1> SELECT * FROM performance_schema.replication_group_member_stats\G *************************** 1. row *************************** CHANNEL_NAME: group_replication_applier VIEW_ID: 1428497631:1 MEMBER_ID: e38fdea8-dded-11e4-b211-e8b1fc3848de COUNT_TRANSACTIONS_IN_QUEUE: 0 COUNT_TRANSACTIONS_CHECKED: 12 COUNT_CONFLICTS_DETECTED: 5 COUNT_TRANSACTIONS_VALIDATING: 6 TRANSACTIONS_COMMITTED_ALL_MEMBERS: 8a84f397-aaa4-18df-89ab-c70aa9823561:1-7 LAST_CONFLICT_FREE_TRANSACTION: 8a84f397-aaa4-18df-89ab-c70aa9823561:7
组复制内部架构
组复制作为一个MySQL插件实现,内部复用了很多现有的代码

插件跟MySQL server层和复制架构层高度集成,利用了现有的binlog、relay log、GTID、从库复制线程、applier等,所以熟悉MySQL的读者能从中发现很多熟悉的东西,没有什么太多的区别。但是于此同时,为了能和其他组件更好的协作,MySQL内部做了一系列重构,模块化抽象等。
桔红色的为插件层,从图上可以看出,最上层为和server层交互的接口,在事务执行的各个阶段都有留下hook,插件能感知事物生命周期的各个阶段。反过来,通过这些接口,插件也能控制MySQL的行为,如什么时候能真正向客户端返回事务已提交。
接口层往下为各具体功能模块。
Capture模块用来跟踪记录事物实行的上下文;
Applier模块用来应用(执行)远程事务,类似从库的apply线程;
Recovery模块用来实现节点的恢复功能,或者帮助新节点和现有节点同步等。
再往下是复制协议层,包括了冲突检测、事务接收、传播等复制相关的逻辑。
最底下是组通信的API层,封装了corosync的一些细节,能更方便的被上层调用。最下面的紫色部分是corosync逻辑,实现了组内通信。
组复制高可用
一般来说,一个能够容错的系统,会利用冗余、复制,将一个节点的状态复制到其他独立节点上,即使其中的某些节点宕机,整个系统依旧可用(虽然可能会有降级,比如性能下降等)
组复制很好的实现了上面提到的特性。故障会被组内通信协议发现并追踪,并隔离到独立节点上。故障恢复协议会被用来自动将节点维持到最新状态。组复制不需要failover,多点写入的特性也保证了节点故障也不会导致写入阻塞。
需要注意的是,虽然数据库服务整体是高可用的状态,但是遇到某个节点宕机,和这个节点通信的客户端需要做重连操作。这个不是组复制本身要考虑的事情,客户端连接池、负载均衡器等都可以用来解决这个问题。
另外,当有新节点加入的时候,可能需要一定的时间才能使新节点和现有节点保持同步,建议全量文件同步加增量复制的方式,这将大大降低同步的时间。
本文转载自本人博客http://hbprotoss.github.io/post/mysql组复制-初见/
主要翻译自MySQL高可用团队博客[MySQL Group Replication : Hello World! | MySQL High Availability](
今天带大家了解了MySQL、数据库、高可用的相关知识,希望对你有所帮助;关于数据库的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~
浅析MySQL的事务隔离
- 上一篇
- 浅析MySQL的事务隔离
- 下一篇
- 四种常见链表的实现及时间复杂度分析(Python3版)
-
- 生动的钢笔
- 写的不错,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢博主分享文章!
- 2023-02-22 14:19:20
-
- 伶俐的小松鼠
- 这篇博文真是及时雨啊,细节满满,很棒,码起来,关注楼主了!希望楼主能多写数据库相关的文章。
- 2023-02-18 20:23:44
-
- 苹果刺猬
- 太全面了,已收藏,感谢楼主的这篇文章内容,我会继续支持!
- 2023-02-12 03:35:10
-
- 含蓄的百褶裙
- 这篇文章真及时,老哥加油!
- 2023-02-12 02:28:39
-
- 长情的钢笔
- 很棒,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢老哥分享文章!
- 2023-02-08 09:05:14
-
- 魁梧的帆布鞋
- 这篇文章内容真及时,很详细,真优秀,码住,关注老哥了!希望老哥能多写数据库相关的文章。
- 2023-01-24 01:03:16
-
- 激昂的绿草
- 这篇文章内容真是及时雨啊,细节满满,太给力了,码起来,关注up主了!希望up主能多写数据库相关的文章。
- 2023-01-17 08:03:08
-
- 迷人的黑猫
- 很好,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢师傅分享技术文章!
- 2023-01-11 00:39:44
-
- 数据库 · MySQL | 53分钟前 |
- MySQL 递归 CTE 生成日期序列时为什么列类型会截断
- 104浏览 收藏
-
- 数据库 · MySQL | 4小时前 |
- MySQL 递归 CTE 遍历树数据时怎么防止无限循环
- 142浏览 收藏
-
- 数据库 · MySQL | 7小时前 |
- MySQL invisible index 如何安全观察索引下线影响
- 300浏览 收藏
-
- 数据库 · MySQL | 8小时前 | MySQL · 索引优化 · generated column · mysql 索引 优化器 生成列
- MySQL 生成列索引为什么没有被优化器使用
- 300浏览 收藏
-
- 数据库 · MySQL | 11小时前 |
- MySQL 窗口函数取每组最新记录时如何处理并列时间
- 242浏览 收藏
-
- 数据库 · MySQL | 12小时前 |
- MySQL JSON_VALUE 返回 NULL 时怎么区分缺少路径和空值
- 170浏览 收藏
-
- 数据库 · MySQL | 14小时前 | MySQL · JSON查询 · JSON_TABLE · SQL技巧 · mysql JSON_TABLE FOR ORDINALITY JSON数组序号
- MySQL JSON_TABLE 的 FOR ORDINALITY 怎么保留数组原始序号
- 139浏览 收藏
-
- 数据库 · MySQL | 16小时前 |
- MySQL 复制延迟升高时怎么区分 SQL 线程和 IO 线程
- 304浏览 收藏
-
- 数据库 · MySQL | 18小时前 | MySQL事件 · 事件调度器 · 任务表排查 · mysql 定时任务 CREATE EVENT Event Scheduler INFORMATION_SCHEMA.EVENTS
- MySQL 事件调度器执行了但任务表没有更新怎么排查
- 486浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 51次使用
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 201次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 137次使用
-
- AI Prompt Library
- 探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
- 68次使用
-
- Generrated
- Generrated汇集9300+张DALL·E生成图像及对应提示词,支持查看完整图集、对比DALL·E 2与3版本差异,是AI绘图新手学习Prompt设计与获取创作灵感的实用工具。
- 49次使用
-
- MySQL 明明加了索引,为什么查询还是很慢?先查这 6 个点
- 2026-06-27 374浏览
-
- 接口返回的数据和数据库不一致怎么办?按数据生命周期排查
- 2026-06-27 398浏览
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- golang 基于 mysql 简单实现分布式读写锁
- 2023-01-07 384浏览
-
- 详解如何利用GORM实现MySQL事务
- 2023-01-07 184浏览
