从MySQL 5.5到5.7看复制的演进

概要:MySQL 5.5 支持单线程模式复制,MySQL 5.6 支持库级别的并行复制,MySQL 5.7 支持事务级别并行复制。结合这个主线我们可以来分析一下MySQL以及社区发展的一个前因后果。

MySQL5.5,对于复制我们可以这样理解:主库有个 dump binlog thread 不停的 dump binlog,然后以event为单位发送给从库 的 iothread,iothread 收到主库传过来的event写入relaylog ,随后sql_thread 读取relaylog 对这些event以事务为单位进行回放。

那么对于MySQL 5.5这个版本,在我们的使用过程中遇到那些问题,或者有那些不便呢?

  • 首先DB压力偏大时,从库带来的延迟较大,影响只读业务

    由于新硬件的发展,SSD的引入和多core的CPU,master节点的并发处理能力持续提升,slave节点完全按照binlog写入顺序的单线程回放,已完全跟不上master节点的吞吐能力。

    在不考虑主从硬件配置差异情况下,延迟大的其根本原因在于:Master压力过大,而Slave是单线程回放日志。那么要解决这个问题,从技术上来说可以把单线程变为多线程,利用并行带来的优势;从业务上来说可以进行拆库,把一些业务线或者功能模块独立出去;更进一步我们可以拆表,把压力分担到多个Master上去。

    1. 假如我们在不变动业务的情况下,从技术面来解决这个问题有哪些方向呢:

      • 社区的解决方案:阿里开源的canal,基于表级别并行同步,可以减小同步延迟时间
      • 官方的解决方案:在2011年10月份发布了一个里程碑版本基于schema级别的并行复制[MySQL5.6.3 (multi-threaded slave)],以及基于group Commit的 MySQL5.7版本,最大化还原主库并行度。

      MySQL5.6,对于复制我们可以这样理解,主库有个 dump binlog thread 不停的 dump binlog,然后以event为单位发送给从库 的 iothread,iothread 收到主库传过来的event写入relaylog。【随后的事情和MySQL5.5就发生了一些变化】,由coordinator线程来读取relaylog,然后根据不同的db以事务为单位分配到不同的work线程。如果binlog row event操作的是不同的schema的对象,在确定没有DDL和foreign key依赖的情况下,就可以实现并行复制。

      MySQL5.7可以说是最大还原了主库上的并行,在基于Group Commit的基础上,所有在主库上能够完成prepared的语句表示没有数据冲突,分配成相同的lastcommitted,就可以在slave节点并行复制。 那么它是如何识别那些事务是一起提交的呢?其实就是在gtid event 中增加了两个字段【int64 lastcommitted;int64 sequencenumber】,当slave的coordinator线程在分发这些event的时候,具有相同lastcommitted 的事务(event的集合)就可以同时发送给不同的work线程,达到并行同步的目的。

      小结:就并行复制,按粒度区分有三种策略,粒度从粗到细是按库、按表、按行。 这三个的对比中,并行度越来越大,额外损耗也是。无关大事务不会影响并发度。按照commit_id 的策略,适用范围更广,额外消耗也低。5.7的改进策略并发性更优。但出现大事务会拖后腿。

    2. 那么我们只有一实例只有一个database,这种情况下我们就只有拆库拆表了:

      对于这种情况下,我们可以选择在应用层做分库分表,也可以选择搞个中间层。不同的方案有不同的优劣。

      • 应用层具有较好的性能,但是代码耦合在业务,如果后续扩容还需该代码,不能做到平滑扩容拆分,假如有多个业务都需要实现同样的功能,那么会带来重复的工作量,而且工作难度也上升一个台阶。
      • 中间件层具有较好的扩展性,低耦合性,如果DB扩容拆分,应用可以做到无感知,无改动。那么也有一些成熟的开源方案,比如MyCAT,Cobar,Atlas,kingshard等。
  • 其次主从切换时带来的复杂度较大,需要计算position或者重做从库

    一般情况下我们的MySQL都是一主多从架构,这样既能给我们提供读写分离、负载均衡的便利,也能给我们提供容灾的能力。但是假如我们的主库挂掉,这时我们会把从库提升为主库,但是在把从库提升为新主的时候带来了架构的微变化。为了还能利用以上便利、提供容灾能力我们还得重新构建这个新主的多个从库。此时问题就来了,我们从库必须知道我当前应该从Master 的那个位置开始复制,也就是说必须拿到Master的position 。为了拿到这个位置我们有两种办法,一种简单粗暴,重做Slave;另一种是通过一些列复杂计算、补回差异数据,算出当前数据和新主数据的差异点,从而得到新主库position,导致HA切换和数据保护带来巨大的挑战。

    • MMM架构(Master-Master replication manager for MySQL)

      MMM是一套支持双主故障切换和双主日常管理的脚本程序,可以再主库故障时保证热备切换为新主库,并且自动的将从库指向新主。但是这个架构本身不能保证数据的一致性。

    • MHA架构(Master High Availability)

      MHA目前在MySQL高可用方面是一个相对成熟的解决方案,在自动进行故障切换的过程中,能最大程度上保证数据的一致性,以达到真正意义上的高可用。

      那么HMA是如何最大程度保证数据一致的呢?当主库down掉时,MHA试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。如果主库发送down机,日志会出现不同程度的丢失,有个解决办法就是设置半同步复制。MHA在把从提升为主的过程中,会进行一系列日志对比,找到最接近主库的从库提升为新主库,把从库间差异化的数据拿出来进行应用等等。

    • GTID (Global Transaction ID)

      在MySQL 5.6 以后官方引入了GTID,即在整个集群内部,每个事务都有全局唯一的一个标识,这样一来,当我们主库发送down掉,或者MySQL架构有调整的时候,我们就不用很头疼的去计算position;或者去配置略为复杂的MHA。我们只需要轻轻松松敲个CHANGE MASTER 命令带上AUTO_POSITION就可以了,然后关于MASTER该从哪个binlog开始推送event给Slave这个完全由MySQL来帮我们计算。这个真是DBA们的福音啊。

      简单看看,为什么这么GTID这么神奇吧。在MySQL内部帮我们记录着 gtidpurged 和gtidexecuted 两个集合。顾名思义,gtidexecuted 代表的时当前已经执行过的GTID的集合;一般情况下我们binlog不可能永久保存,那么gtidpurged代表的就是当前binlog已经没有的GTID集合,它是gtidexecuted的子集。我们知道在事务是不能跨binlog存在的,意味着每个binlog都会有一个完整的事务集合,同样每个binlog文件的 header 部分,也都存放着这个binlog以前的 gtidexecuted 集合。我们的Slave 在应用Binlog的时候都会记录自己当前已经执行过的最后一个事务GTID,那么我们在切换主库的时候,Slave就会把这个ID给带上,然后Master端就会拿到这个GTID和自己当前的gtidexecuted、gtidpurged 集合进行对比,从而给到Slave一个合理的解释。

OK,到这里MySQL从5.5的单线程复制,到5.6基于Schema级别的复制,再到5.7最大化还原主库的并行就接近尾声了。同时在这期间我们还给出了一些社区上、或者非技术上的解决方案。

时间: 2024-10-20 00:27:58

从MySQL 5.5到5.7看复制的演进的相关文章

MySQL互为主从模型实现基于SSL复制

一.MySQL复制 1.MySQL复制过程描述 MySQL主服务器上每一次发生的有可能产生修改或者产生修改的操作都会在主服务器上基于语句或基于行写入二进制日志,从服务器会在此期间启用一个IO线程不断的向主服务器发送请求,主服务器的二进制日志一但有更新,则会启用binlog dump线程,把数据发送给对方,从服务器接收到数据后则会将二进制日志的内容同步至本地的中继日志保存,而后启用SQL线程,将日志中的操作语句写入本地从服务器数据库: 2.mysql复制的同步和异步 同步:客户端向主服务器执行一条

第四阶段 (七)MySQL REPLICATION(主从复制、半同步复制、复制过滤)

Linux运维 第四阶段 (七)MySQL REPLICATION(主从复制.半同步复制.复制过滤) 一.MySQL Replication相关概念: 1.复制的作用:辅助实现备份:高可用HA:异地容灾:分摊负载(scaleout):rw-spliting(mysql proxy工作在应用层). 2.master有多个CPU允许事务并行执行,但往二进制日志文件只能一条条写:slave比master要慢:master-slave默认异步方式传送. 3.半同步:仅负责最近一台slave同步成功,其它

Mysql实现数据库主从复制、主主复制、半同步复制

--------------Mysql实现数据库主从复制架构---------------- 一.环境准备: centos系统服务器2台.一台用户做Mysql主服务器,一台用于做Mysql从服务器,配置好yum源.防火墙关闭.各节点时钟服务同步.各节点之间可以通过主机名互相通信 192.168.41.145   master 192.168.41.137  slave 二.准备步骤: 1.iptables -F && setenforce 清空防火墙策略,关闭selinux 2.①vim

MySQL增删改插 及表的复制及改名

MySQL增.删.改.插全表查询表记录格式1:select 字段1,...字段N from 库名.表名; 格式2:select 字段1,...字段N from 库名.表名 where 条件表达式; 注意事项:1.使用"*"可匹配所有字段.2.指定表名时,可采用 库名.表名 的形式 例: mysql>create database ku; mysql>create table ku.lisi( >name char(10) not null, >gender en

mysql优化原理,一定要看懂

转:     https://www.jianshu.com/p/d7665192aaaf 我必须得告诉大家的MySQL优化原理 说起MySQL的查询优化,相信大家收藏了一堆奇技淫巧:不能使用SELECT *.不使用NULL字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解其背后的工作原理?在实际场景下性能真有提升吗?我想未必.因而理解这些优化建议背后的原理就尤为重要,希望本文能让你重新审视这些优化建议,并在实际业务场景下合理的运用. MySQL逻辑架构

MySQL学习总结,希望可以看的懂!

1.数据库概述 简而言之,数据库(DataBase)就是一个存储数据的仓库.为了方便数据的存储和管理,将数据按照特定的规律存储在磁盘上.通过数据库管理系统,可以有效的组织和管理存储在数据库中的数据.如今,已经存在的Oracle.SQLServer.MySQL等诸多优秀的数据库.  详解内容:  数据存储方式  数据库在开发中的作用  数据库访问技术  MySQL数据库的介绍  数据库泛型  SQL语言  常见数据库系统  如果学习数据库  1.1 数据库理论基础  数据库能够将数据按照特定的规律

架构师必看 京东咚咚架构演进

原文地址:http://developer.51cto.com/art/201512/500645.htm 咚咚是什么?咚咚之于京东相当于旺旺之于淘宝,它们都是服务于买家和卖家的沟通. 自从京东开始为第三方卖家提供入驻平台服务后,咚咚也就随之诞生了. 我们首先看看它诞生之初是什么样的. 1.0 诞生(2010 – 2011) 为了业务的快速上线,1.0 版本的技术架构实现是非常直接且简单粗暴的. 如何简单粗暴法?请看架构图,如下. 1.0 的功能十分简单,实现了一个 IM 的基本功能,接入.互通

MySQL(MariaDB)的 SSL 加密复制

背景: 在默认的主从复制过程或远程连接到MySQL/MariaDB所有的链接通信中的数据都是明文的,在局域网内连接倒问题不大:要是在外网里访问数据或则复制,则安全隐患会被放大很多.由于项目要求需要直接和外网的一台实例进行同步.所以本文介绍下通过SSL加密的方式进行复制的方法,来进一步提高数据的安全性.本文会一起介绍MySQL和MariaDB. 环境搭建: 默认情况下ssl都是关闭的,要是have_ssl显示NO,则表示数据库不支持SSL,需要重新编译安装来支持它,显示为DISABLED表示支持S

MySQL压测--异步与半同步复制

最近在看MySQL5.7 Manual,有关Semisynchronous Replication这一块的内容,我们知道,MySQL默认的Replication是异步的,何为异步?何为半同步?废话不多说,直接看官方解释吧: 1.背景知识 Asynchronous replication the master writes events to its binary log and slaves request them when they are ready. There is no guaran