MySQL Replication中的并行复制示例详解

目录
  • 传统单线程复制说明
  • 总结
  • MySQL5.6基于库级别的并行复制
    • MySQL5.7基于组提交的并行复制
    • 组提交说明
  • MySQL8.0基于writeset的并行复制
    • 关键参数查看
    • 参数配置项说明
  • 引用资料:

传统单线程复制说明

众所周知,MySQL在5.6版本之前,主从复制的从节点上有两个线程,分别是I/O线程和SQL线程。

  • I/O线程负责接收二进制日志的Event写入Relay Log。
  • SQL线程读取Relay Log并在数据库中进行回放。

以上方式偶尔会造成延迟,那么可能造成主从节点延迟的情况有哪些?

  • 1.主库执行大事务(如:大表结构变更操作)。
  • 2.主库大批量变更(如:大量插入、更新、删除操作)。
  • 3.ROW同步模式下,主库大表无主键频繁更新。
  • 4.数据库参数配置不合理,从节点性能存在瓶颈(如:从节点事务日志设置过小,导致频繁刷盘)。
  • 5.网络环境不稳定,从节点IO线程读取binlog存在延迟、重连情况。
  • 6.主从硬件配置差异,从节点的硬件资源使用达到上限。(比如:主节点SSD盘,从节点SAS盘)

可以对以上延迟原因做个大致分类。

  • 1.硬件方面问题(包括磁盘IO、网络IO等)
  • 2.配置方面问题。
  • 3.数据库设计问题。
  • 4.主库大批量变更,从节点SQL单线程处理不够及时。

总结

分析以上原因可以看出要想降低主从延迟,除了改善硬件方面条件之外,另外就是需要DBA关注数据库设计和配置问题,最后就是需要提高从节点的并发处理能力,由单线程回放改为多线程并行回放是一个比较好的方法,关键点在于如何在多线程恢复的前提下解决数据冲突和故障恢复位置点的确认问题。

MySQL5.6基于库级别的并行复制

在实例中有多个数据库的情况下,可以开启多个线程,每个线程对应一个数据库。该模式下从节点会启动多个线程。线程分为两类 Coordinator 和 WorkThread

  • 线程分工执行逻辑

Coordinator线程负责判断事务是否可以并行执行,如果可以并行就把事务分发给WorkThread线程执行,如果判断不能执行,如DDL跨库操作等,就等待所有的worker线程执行完成之后,再由Coordinator执行。

  • 关键配置信息
slave-parallel-type=DATABASE
  • 方案不足点

这种并行复制的模式,只有在实例中有多个DB且DB的事务都相对繁忙的情况下才会有较高的并行度,但是日常维护中其实单个实例的的事务处理相对集中在一个DB上。通过观察延迟可以发现基本上都是基于热点表出现延迟的情况占大多数。如果能够提供基于表的并行度是一个很好方法。

MySQL5.7基于组提交的并行复制

组提交说明

简单来说就是在双1的设置下,事务提交后即刷盘的操作改为多个事务合并成一组事务再进行统一刷盘,这样处理就降低了磁盘IO的压力。详细资料参考老叶茶馆关于组提交的说明推文https://mp.weixin.qq.com/s/rcPkrutiLc93aTblEZ7sFg

一组事务同时提交也就意味着组内事务不存在冲突,故组内的事务在从节点上就可以并发执行,问题在于如何区分事务是否在同一组中的,于是在binlog中出现了两个新的参数信息last_committed 和 sequence_number

  • 如何判断事务在一个组内呢?

解析binlog可以发现里面多了last_committedsequence_number两个参数信息,其中last_committed存在重复的情况。

  • sequence_number # 这个值指的是事务提交的序号,单调递增。
  • last_committed # 这个值有两层含义,1.相同值代表这些事务是在同一个组内,2.该值同时又是代表上一组事务的最大编号。
[root@mgr2 GreatSQL]# mysqlbinlog mysql-bin.0000002 | grep last_committed
GTID last_committed=0 sequence_number=1
GTID last_committed=0 sequence_number=2
GTID last_committed=2 sequence_number=3
GTID last_committed=2 sequence_number=4
GTID last_committed=2 sequence_number=5
GTID last_committed=2 sequence_number=6
GTID last_committed=6 sequence_number=7
GTID last_committed=6 sequence_number=8
  • 数据库配置
slave-parallel-type=LOGICAL_CLOCK
  • 方案不足点

基于组提交的同步有个不足点,就是当主节点的事务繁忙度较低的时候,导致时间段内组提交fsync刷盘的事务量较少,于是导致从库回放的并行度并不高,甚至可能一组里面只有一个事务,这样从节点的多线程就基本用不到,可以通过设置下面两个参数,让主节点延迟提交。

  • binlog_group_commit_sync_delay # 等待延迟提交的时间,binlog提交后等待一段时间再 fsync。让每个 group 的事务更多,人为提高并行度。
  • binlog_group_commit_sync_no_delay_count # 待提交的最大事务数,如果等待时间没到,而事务数达到了,就立即 fsync。达到期望的并行度后立即提交,尽量缩小等待延迟。

MySQL8.0基于writeset的并行复制

writeset 基于事务结果冲突进行判断事务是否可以进行并行回放的方法,他由binlog-transaction-dependency-tracking参数进行控制,默认采用WRITESET方法。

关键参数查看

Command-Line Format --binlog-transaction-dependency-tracking=value
System Variable binlog_transaction_dependency_tracking
Scope Global
Dynamic Yes
SET_VAR Hint Applies No
Type Enumeration
Default Value COMMIT_ORDER
Valid Values COMMIT_ORDER
WRITESET
WRITESET_SESSION

参数配置项说明

  • COMMIT_ORDER # 使用 5.7 Group commit 的方式决定事务依赖。
  • WRITESET     # 使用写集合的方式决定事务依赖。
  • WRITESET_SESSION # 使用写集合,但是同一个session中的事务不会有相同的last_committed。

writeset 是一个HASH类型的数组,里面记录着事务的更新信息,通过transaction_write_set_extraction判断当前事务更新的记录与历史事务更新的记录是否存在冲突,判断过后再采取对应处理方法。writeset储存的最大存储值由binlog-transaction-dependency-history-size控制。

需要注意的是,当设置成WRITESETWRITESET_SESSION的时候,事务提交是无序状态的,可以通过设置 slave_preserve_commit_order=1 强制按顺序提交。

  • binlog_transaction_dependency_history_size

设置保存在内存中的行哈希数的上限,用于缓存之前事务修改的行信息。一旦达到这个哈希数,就会清除历史记录。

Command-Line Format --binlog-transaction-dependency-history-size=#
System Variable binlog_transaction_dependency_history_size
Scope Global
Dynamic Yes
SET_VAR Hint Applies No
Type Integer
Default Value 25000
Minimum Value 1
Minimum Value 1000000
  • transaction_write_set_extraction

该模式支持三种算法,默认采用XXHASH64,当从节点配置writeset复制的时候,该配置不能配置为OFF。该参数已经在MySQL 8.0.26中被弃用,后续将会进行删除。

Command-Line Format --transaction-write-set-extraction[=value]
Deprecated 8.0.26
System Variable binlog_transaction_dependency_history_size
Scope Global, Session
Dynamic Yes
SET_VAR Hint Applies No
Type Enumeration
Default Value XXHASH64
Valid Values OFF
MURMUR32
XXHASH64

数据库配置

slave_parallel_type = LOGICAL_CLOCK
slave_parallel_workers = 8
binlog_transaction_dependency_tracking = WRITESET
slave_preserve_commit_order = 1

引用资料:

到此这篇关于MySQL Replication之并行复制的文章就介绍到这了,更多相关MySQL 并行复制内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 浅析MySQL的WriteSet并行复制

    [历史背景] 岁月更迭中我已经从事MySQL-DBA这个工作三个年头,见证MySQL从"基本可用","边缘系统可以用MySQL","哦操!你怎么不用MySQL"; 正所谓!"一个数据库的境遇既取决于历史的进程,取决于它的自我奋斗!",关于"历史的进程"在此不表,关于"自我奋斗"这里也只想谈一下并行复制的几个关键时间结点 总的来说MySQL关于并行复制到目前为止经历过三个比较关键的时间结点

  • MySQL-group-replication 配置步骤(推荐)

    MySQL-Group-Replication 是mysql-5.7.17版本开发出来的新特性:它在master-slave 之间实现了强一致性, 但是就目前来说主要是性能不太好. [1]确定当前的mysql数据库版本为5.7.17及以上 /usr/local/mysql/bin/mysqld --version /usr/local/mysql/bin/mysqld Ver 5.7.17 for linux-glibc2.5 on x86_64 (MySQL Community Server

  • mysql容器之间的replication配置实例详解

    背景 上周公司培训了MySQL replication, 这个周末打算用所学来实践操作一下. Master server:MySQL container mysql_master on NAS NAS server IP: 192.168.1.108 mysql_master inner ip: 172.17.0.6 Slave server: MySQK container mysql_slave on Mac mini Mac mini docker host IP: 192.168.1.1

  • 浅析MySQL并行复制

    01 并行复制的概念 在MySQL的主从复制架构中,主库上经常会并发的执行很多SQL,只要这些SQL没有产生锁等待,那么同一时间并发好几个SQL线程是没有问题的. 我们知道,MySQL的从库是要通过IO_thread去拉取主库上的binlog的,然后存入本地,落盘成relay-log,通过sql_thread来应用这些relay-log. 在MySQL5.6之前的版本中,当主库上有多个线程并发执行SQL时,sql_thread只有一个,在某些TPS比较高的场景下,会出现主库严重延迟的问题.MyS

  • 深入浅出讲解MySQL的并行复制

    一.并行复制的背景 首先,为什么会有并行复制这个概念呢? 1. DBA都应该知道,MySQL的复制是基于binlog的. 2. MySQL复制包括两部分,IO线程 和 SQL线程. 3. IO线程主要是用于拉取接收Master传递过来的binlog,并将其写入到relay log 4. SQL线程主要负责解析relay log,并应用到slave中 5. 不管怎么说,IO和SQL线程都是单线程的,然后master却是多线程的,所以难免会有延迟,为了解决这个问题,多线程应运而生了. 6. IO多线

  • MySQL Semisynchronous Replication介绍

    前言 MySQL 5.5版本之前默认的复制是异步(Asynchronous )模式的, MySQL 5.5 以plugins的方式提供了Semisynchronous Replication 模式.在介绍 semi sync 之前,我们先了解:半同步 Asynchronous 和 同步 Synchronous . 异步复制模式 主库将已经提交的事务event 写入binlog后,即返回成功给app,该模式下并不保证任何已经提交的事务会传递到任何slave并被成功应用. 全同步复制模式. 当主库提

  • 基于mysql replication的问题总结

    接触replication后,就开始琢磨自己要配置下试试,固然出现了很多问题:经过上网查资料也好问同学也好,终于是解决了些.现在就分享下自己的经历: 首先的问题是配置master的my.cnf,按部就班的配置 复制代码 代码如下: server-id               = 1  log_bin                 =mysql-bin  #log_bin                        = /var/log/mysql/mysql-bin.log  expir

  • MySQL Replication中的并行复制示例详解

    目录 传统单线程复制说明 总结 MySQL5.6基于库级别的并行复制 MySQL5.7基于组提交的并行复制 组提交说明 MySQL8.0基于writeset的并行复制 关键参数查看 参数配置项说明 引用资料: 传统单线程复制说明 众所周知,MySQL在5.6版本之前,主从复制的从节点上有两个线程,分别是I/O线程和SQL线程. I/O线程负责接收二进制日志的Event写入Relay Log. SQL线程读取Relay Log并在数据库中进行回放. 以上方式偶尔会造成延迟,那么可能造成主从节点延迟

  • Mysql联表update数据的示例详解

    1.MySQL UPDATE JOIN语法 在MySQL中,可以在 UPDATE语句 中使用JOIN子句执行跨表更新.MySQL UPDATE JOIN的语法如下: UPDATE T1, T2, [INNER JOIN | LEFT JOIN] T1 ON T1.C1 = T2. C1 SET T1.C2 = T2.C2, T2.C3 = expr WHERE condition 更详细地看看MySQL UPDATE JOIN语法: 首先,在UPDATE子句之后,指定主表(T1)和希望主表连接表

  • MySQL教程数据定义语言DDL示例详解

    目录 1.SQL语言的基本功能介绍 2.数据定义语言的用途 3.数据库的创建和销毁 4.数据库表的操作(所有演示都以student表为例) 1)创建表 2)修改表 3)销毁表 如果你是刚刚学习MySQL的小白,在你看这篇文章之前,请先看看下面这些文章.有些知识你可能掌握起来有点困难,但请相信我,按照我提供的这个学习流程,反复去看,肯定可以看明白的,这样就不至于到了最后某些知识不懂却不知道从哪里下手去查. <MySQL详细安装教程> <MySQL完整卸载教程> <这点基础都不懂

  • Swift 中的 JSON 反序列化示例详解

    目录 业界常用的几种方案 手动解码方案,如 Unbox(DEPRECATED) 阿里开源的 HandyJSON 基于 Sourcery 的元编程方案 Swift build-in API Codable 属性装饰器,如 BetterCodable 各个方案优缺点对比 Codable 介绍 原理浅析 Decoder.Container 协议 自研方案 功能设计 Decoder.Container 具体实现 再议 PropertyWrapper 应用场景示例 单元测试 性能对比 业界常用的几种方案

  • MySQL实现数据插入操作的示例详解

    目录 一.方法分类 二.具体方法 三.实例 (1)常规插入 (2)从另一个表导入 (3)插入时数据重复 四.注意事项 (1)不写字段名,需要填充自增ID (2)按字段名填充,可以不录入id 其余注意事项 使用MySQL插入数据时,可以根据需求场景选择合适的插入语句,例如当数据重复时如何插入数据,如何从另一个表导入数据,如何批量插入数据等场景.本文通过给出每个使用场景下的实例来说明数据插入的实现过程和方法. 一.方法分类 二.具体方法 使用场景 作用 语句 注意 常规插入 忽略字段名 insert

  • MySQL数据类型中DECIMAL的用法实例详解

    MySQL数据类型中DECIMAL的用法实例详解 在MySQL数据类型中,例如INT,FLOAT,DOUBLE,CHAR,DECIMAL等,它们都有各自的作用,下面我们就主要来介绍一下MySQL数据类型中的DECIMAL类型的作用和用法. 一般赋予浮点列的值被四舍五入到这个列所指定的十进制数.如果在一个FLOAT(8, 1)的列中存储1. 2 3 4 5 6,则结果为1. 2.如果将相同的值存入FLOAT(8, 4) 的列中,则结果为1. 2 3 4 6. 这表示应该定义具有足够位数的浮点列以便

  • C语言中的正则表达式使用示例详解

    正则表达式,又称正规表示法.常规表示法(英语:Regular Expression,在代码中常简写为regex.regexp或RE).正则表达式是使用单个字符串来描述.匹配一系列符合某个句法规则的字符串. 在c语言中,用regcomp.regexec.regfree 和regerror处理正则表达式.处理正则表达式分三步: 编译正则表达式,regcomp: 匹配正则表达式,regexec: 释放正则表达式,regfree. 函数原型 /* 函数说明:Regcomp将正则表达式字符串regex编译

  • Flutter 中 Dart的Mixin示例详解

    原文在这里.写的不错,推荐各位看原文. 这里补充一下Mixin的定义: 只要一个类是继承自Object的而且没有定义构造方法,那么这个类可以是一个Mixin了.当然,如果你想让mixin的定义更加的清晰,可以使用mixin关键字开头来定义.具体请参考这里 原文截图体会一下风格. 正文 在经典的面向对象编程语言里一定会有常规的类,抽象类和接口.当然,Dart也有它自己的接口,不过那是另外的文章要说的.有的时候阴影里潜伏者另外的野兽:Mixin!这是做什么的,如何使用?我们来一起发现. 没有mixi

  • shrio中hashedCredentialsMatcher密码匹配示例详解

    类图如下: SimpleCredentialsMatcher是明文匹配,也是shrio框架默认的比对方式,网上的例子多是此方式.实际项目中,数据库中的密码一般是密文,此时密码的匹配需使用HashedCredentialsMatcher完成. 处理过程 在controller中通过Subject的login(token)将接收过来用户账号和密码(明文)交给shrio框架,示例代码如下 其次通过HashedCredentialsMatcher告诉shrio使用加密方式: 最后通过Authorizin

  • Java中的反射机制示例详解

    目录 反射 什么是Class类 获取Class实例的三种方式 通过反射创建类对象 通过反射获取类属性.方法.构造器 更改访问权限和实例赋值 运用场景 反射 反射就是把Java类中的各个成分映射成一个个的Java对象.即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法:对于任意一个对象,都能调用它的任意一个方法和属性.这种动态获取信息及动态调用对象方法的功能叫Java的反射机制 每一个Java程序执行必须通过编译.加载.链接和初始化四个阶段 1.编译:将.java.文件编译成字节码.

随机推荐