传统单线程复制说明

众所周知,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基于库级别的并行复制

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

  • 线程分工执行逻辑

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_committedsequence_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
  • 方案不足点

基于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

引用资料:

  • 阿里内核月报:

    http://mysql.taobao.org/monthly/2018/06/04/
  • 官方文档:

    https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-log.html

Enjoy GreatSQL

文章推荐:

GreatSQL季报(2021.12.26)

https://mp.weixin.qq.com/s/FZ_zSBHflwloHtZ38YJxbA

技术分享|sysbench 压测工具用法浅析

https://mp.weixin.qq.com/s/m16LwXWy9bFt0i99HjbRsw

故障分析 | linux 磁盘io利用率高,分析的正确姿势

https://mp.weixin.qq.com/s/7cu_36jfsjZp1EkVexkojw

技术分享|闪回在MySQL中的实现和改进

https://mp.weixin.qq.com/s/6jepwEE0DnYUpjMYO17VtQ

万答#20,索引下推如何进行数据过滤

https://mp.weixin.qq.com/s/pt6mr3Ge1ya2aa6WlrpIvQ

关于 GreatSQL

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

Gitee:

https://gitee.com/GreatSQL/GreatSQL

GitHub:

https://github.com/GreatSQL/GreatSQL

Bilibili:

https://space.bilibili.com/1363850082/video

微信&QQ群:

可搜索添加GreatSQL社区助手微信好友,发送验证信息“加群”加入GreatSQL/MGR交流微信群

QQ群:533341697

微信小助手:wanlidbc

本文由博客一文多发平台 OpenWrite 发布!

MySQL主从复制之并行复制说明的更多相关文章

  1. MySQL 5.7 并行复制实现原理与调优

    MySQL 5.7并行复制时代 众所周知,MySQL的复制延迟是一直被诟病的问题之一,然而在Inside君之前的两篇博客中(1,2)中都已经提到了MySQL 5.7版本已经支持“真正”的并行复制功能, ...

  2. mysql主从复制跳过复制错误【转】

    跳过复制错误 mysql因为binlog机制问题,有些时候会出现从库重放sql执行失败的情况,特别是旧的STATEMENT模式最容易出现这种情况(因为函数和存储过程等原因),这也是为什么强调使用mix ...

  3. 官方:MySQL 5.7 并行复制实现原理与调优 | InsideMySQL(转载)

    MySQL 5.7并行复制时代 众所周知,MySQL的复制延迟是一直被诟病的问题之一,然而在Inside君之前的两篇博客中(1,2)中都已经提到了MySQL 5.7版本已经支持“真正”的并行复制功能, ...

  4. MySQL 5.7并行复制时代

    众所周知,MySQL的复制延迟是一直被诟病的问题之一,然而在Inside君之前的两篇博客中(1,2)中都已经提到了MySQL 5.7版本已经支持“真正”的并行复制功能,官方称为为enhanced mu ...

  5. Mysql5.7实现主从复制、基于GTID的主从复制、并行复制

    (一.主从复制) 一.mysql主从复制原理    mysql的默认复制方式是主从复制.Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制, ...

  6. MySQL 5.7 并行复制

    一.缘由: 某天看到主从复制延时的告警有点频繁,就想着是不是彻底可以解决一下. 一般主从复制,有三个线程参与,都是单线程:Binlog Dump(主) ----->IO Thread (从) - ...

  7. 谈谈MySQL的WriteSet并行复制

    [历史背景] 岁月更迭中我已经从事MySQL-DBA这个工作三个年头,见证MySQL从“基本可用”,“边缘系统可以用MySQL”,“哦操!你怎么不用MySQL”; 正所谓!“一个数据库的境遇既取决于历 ...

  8. mysql 5.6并行复制事件分发机制

    并行复制相关线程 在MySQL 5.6并行复制中,当设置set global slave_parallel_workers=2时,共有4个复制相关的线程,如下: +----+------------- ...

  9. MySQL主从复制(异步复制与半同步复制)

    1.MySQl主从复制 原理:将主服务器的binlog日志复制到从服务器上执行一遍,达到主从数据的一致状态. 过程:从库开启一个I/O线程,向主库请求Binlog日志.主节点开启一个binlog du ...

随机推荐

  1. declare-声明限定类型变量

    用于声明变量并设置变量的属性. 语法 declare [+/-][rxi][变量名称=设置值] declare -f 特殊符号 +/- "-"可用来指定变量的属性,"+& ...

  2. 「ABC 249Ex」Dye Color

    考虑停时定理. 初始势能为 \(\sum \Phi(cnt_i)\),末势能为 \(\Phi(n)\),我们希望构造这样一个 \(\Phi:Z\to Z\) 函数,使得每一次操作期望势能变化量为常数. ...

  3. static关键字——JavaSE基础

    static关键字 由于static跟随类被加载,因此静态代码块.构造方法.匿名代码块的执行顺序为静态代码块→匿名代码块→构造方法 public class Demo01 { public stati ...

  4. 架构师必备:HBase行键设计与应用

    首先要回答一个问题,为何要使用HBase? 随着业务不断发展.数据量不断增大,MySQL数据库存在这些问题: MySQL支持的数据量为TB级,不能一直保留历史数据.而HBase支持的数据量为PB级,适 ...

  5. 『忘了再学』Shell基础 — 26、cut列提取命令

    目录 1.cut命令说明 2.cut命令练习 (1)cut命令基本用法 (2)cut命令选取多列 (3)按字符来进行提取 (4)按指定分隔符进行截取数据 3.cut命令分隔符说明 1.cut命令说明 ...

  6. 数据分析工具Metabase--Metabase安装(最详细的安装教程)

    Meatabase介绍 Metabase 是一款开源的BI工具.主要可以实现在线的可视化分析,单独生成分析图标,定时刷新数据集,权限管理,报告分享等一系列功能. Metabase支持多种市面上主流的数 ...

  7. Linux 装完后没有声音的解决办法

    备注:1)Ubuntu Desktop版本:16.042)Linux工作用户:root1. 临时方法在终端中执行命令:pulseaudio --start --log-target=syslog2. ...

  8. Git出现“filename too long”错误处理

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年5月8日. 怎么肥事? Windows系统下,在Git使用过程中,出现"filename too long"错误提 ...

  9. 基于Kubernetes v1.24.0的集群搭建(三)

    1 使用kubeadm部署Kubernetes 如无特殊说明,以下操作可以在所有节点上进行. 1.1 首先我们需要配置一下阿里源 cat <<EOF > /etc/yum.repos ...

  10. 关于一次Web线下面试的思考

    前言: 今天面试一家Web前端的公司,由于跟初筛的面试官关系挺好,按理来说我在第一次线上面试就应该被淘汰了(呜呜呜),接下来是线下面试,不出意外的话,我凉了.但是这些天的面试经验并非全无收获.我的线下 ...