MySQL组复制-初见
来源:SegmentFault
时间:2023-01-10 13:51:26 495浏览 收藏
在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学习网公众号,一起学习编程~
-
499 收藏
-
244 收藏
-
235 收藏
-
157 收藏
-
101 收藏
-
475 收藏
-
266 收藏
-
273 收藏
-
283 收藏
-
210 收藏
-
371 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习
-
- 生动的钢笔
- 写的不错,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢博主分享文章!
- 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