美文网首页
MySQL的并行复制

MySQL的并行复制

作者: david161 | 来源:发表于2022-04-21 08:40 被阅读0次

MySQL的主从复制延迟一直是受开发者最为关注的问题之一,MySQL从5.6版本开始追加了并行复制功能,目的就是为了改善复制延迟问题,并行复制称为enhanced multi-threaded slave(简称MTS)。
在从库中有两个线程IO Thread和SQL Thread,都是单线程模式工作,因此有了延迟问题,我们可以采用多线程机制来加强,减少从库复制延迟。(IO Thread多线程意义不大,主要指的是SQL Thread多线程)。
在MySQL的5.6、5.7、8.0版本上,都是基于上述SQL Thread多线程思想,不断优化,减少复制延迟。

MySQL 5.6并行复制原理

MySQL 5.6版本也支持所谓的并行复制,但是其并行只是基于库的。如果用户的MySQL数据库中是多个库,对于从库复制的速度的确可以有比较大的帮助。


image.png

基于库的并行复制,实现相对简单,使用也相对简单些。基于库的并行复制遇到单库多表使用场景就发挥不出优势了,另外对事务并行处理的执行顺序也是个大问题。

MySQL 5.7并行复制原理

MySQL 5.7是基于组提交的并行复制,MySQL 5.7才可称为真正的并行复制,这其中最为主要的原因就是slave服务器的回放与master服务器是一致的,即master服务器上是怎么并行执行的slave上就怎样进行并行回放。不再有库的并行复制限制。
MySQL 5.7中组提交的并行复制究竟是如何实现的?
MySQL 5.7是通过对事务进行分组,当事务提交时,它们将在单个操作中写入到二进制日志中。如果多个事务能同时提交成功,那么它们意味着没有冲突,因此可以在Slave上并行执行,所以通过在主库上的二进制日志中添加组提交信息。
MySQL 5.7的并行复制基于一个前提,即所有已经处于prepare阶段的事务,都是可以并行提交的。这些当然也可以在从库中并行提交,因为处理这个阶段的事务都是没有冲突的。在一个组里提交的事务,一定不会修改同一行。这是一种新的并行复制思路,完全摆脱了原来一直致力于为了防止冲突而做的分发算法,等待策略等复杂的而又效率底下的工作。
InnoDB事务提交采用的是两阶段提交模式。一个阶段是prepare,另一个是commit。
为了兼容MySQL 5.6基于库的并行复制,5.7引入了新的变量slave-parallel-type,其可以配置的值有:
DATABASE(默认值,基于库的并行复制方式)、LOGICAL_CLOCK(基于组提交的并行复制方式)。
那么如何知道事务是否在同一组中,生成的Binlog内容如何告诉Slave哪些事务是可以并行复制的?
在MySQL 5.7版本中,其设计方式是将组提交的信息存放在GTID中。为了避免用户没有开启GTID功能(gtid_mode=OFF),MySQL 5.7又引入了称之为Anonymous_Gtid的二进制日志event类型ANONYMOUS_GTID_LOG_EVENT。
通过mysqlbinlog工具分析binlog日志,就可以发现组提交的内部信息。


image.png

可以发现MySQL 5.7二进制日志较之原来的二进制日志内容多了last_committed和
sequence_number,last_committed表示事务提交的时候,上次事务提交的编号,如果事务具有相同的last_committed,表示这些事务都在一组内,可以进行并行的回放。

MySQL8.0 并行复制

MySQL8.0 是基于write-set的并行复制。MySQL会有一个集合变量来存储事务修改的记录信息(主键哈希值),所有已经提交的事务所修改的主键值经过hash后都会与那个变量的集合进行对比,来判断改行是否与其冲突,并以此来确定依赖关系,没有冲突即可并行。这样的粒度,就到了 row级别了,此时并行的粒度更加精细,并行的速度会更快。

并行复制配置与调优

1)binlog_transaction_dependency_history_size
用于控制集合变量的大小。
2)binlog_transaction_depandency_tracking
用于控制binlog文件中事务之间的依赖关系,即last_committed值。
COMMIT_ORDERE: 基于组提交机制
WRITESET: 基于写集合机制
WRITESET_SESSION: 基于写集合,比writeset多了一个约束,同一个session中的事务last_committed按先后顺序递增
3)transaction_write_set_extraction
用于控制事务的检测算法,参数值为:OFF、 XXHASH64、MURMUR32
4)master_info_repository
开启MTS功能后,务必将参数master_info_repostitory设置为TABLE,这样性能可以有50%~80%的提升。这是因为并行复制开启后对于元master.info这个文件的更新将会大幅提升,资源的竞争也会变大。
5)slave_parallel_workers
若将slave_parallel_workers设置为0,则MySQL 5.7退化为原单线程复制,但将
slave_parallel_workers设置为1,则SQL线程功能转化为coordinator线程,但是只有1个worker线程进行回放,也是单线程复制。然而,这两种性能却又有一些的区别,因为多了一次coordinator线程的转发,因此slave_parallel_workers=1的性能反而比0还要差。
6)slave_preserve_commit_order
MySQL 5.7后的MTS可以实现更小粒度的并行复制,但需要将slave_parallel_type设置为LOGICAL_CLOCK,但仅仅设置为LOGICAL_CLOCK也会存在问题,因为此时在slave上应用事务的顺序是无序的,和relay log中记录的事务顺序不一样,这样数据一致性是无法保证的,为了保证事务是按照relay log中记录的顺序来回放,就需要开启参数slave_preserve_commit_order。
要开启enhanced multi-threaded slave其实很简单,只需根据如下设置:

slave-parallel-type=LOGICAL_CLOCK 
slave-parallel-workers=16 
slave_pending_jobs_size_max = 2147483648 
slave_preserve_commit_order=1 
master_info_repository=TABLE 
relay_log_info_repository=TABLE 
relay_log_recovery=ON
并行复制监控

在使用了MTS后,复制的监控依旧可以通过SHOW SLAVE STATUS\G,但是MySQL 5.7在performance_schema库中提供了很多元数据表,可以更详细的监控并行复制过程。

mysql> show tables like 'replication%'; 
+---------------------------------------------+ 
| Tables_in_performance_schema (replication%) | 
+---------------------------------------------+ 
| replication_applier_configuration | 
| replication_applier_status | 
| replication_applier_status_by_coordinator | 
| replication_applier_status_by_worker | 
| replication_connection_configuration | 
| replication_connection_status | 
| replication_group_member_stats | 
| replication_group_members | 
+---------------------------------------------+

通过replication_applier_status_by_worker可以看到worker进程的工作情况:

mysql> select * from replication_applier_status_by_worker;
+--------------+-----------+-----------+---------------+------------------------ 
--------------------+-------------------+--------------------+------------------ 
----+ 
| CHANNEL_NAME | WORKER_ID | THREAD_ID | SERVICE_STATE | LAST_SEEN_TRANSACTION | LAST_ERROR_NUMBER | LAST_ERROR_MESSAGE | LAST_ERROR_TIMESTAMP | 
+--------------+-----------+-----------+---------------+------------------------ 
--------------------+-------------------+--------------------+------------------ 
----+ 
| | 1 | 32 | ON | 0d8513d8-00a4-11e6- a510-f4ce46861268:96604 | 0 | 
| 0000-00-00 00:00:00 | | | 2 | 33 | ON | 0d8513d8-00a4-11e6- a510-f4ce46861268:97760 | 0 | 
| 0000-00-00 00:00:00 | 
+--------------+-----------+-----------+---------------+------------------------ 
--------------------+-------------------+--------------------+------------------ 
----+ 
2 rows in set (0.00 sec)

最后,如果MySQL 5.7要使用MTS功能,建议使用新版本,最少升级到5.7.19版本,修复了很多Bug。

相关文章

  • 2.安装部署

    源码编译 MySQL编译依赖 必备的包和工具 功能需要的包 功能定制 MySQL限流SQL限流并行复制Thread...

  • MySQL并行复制

    传统复制: 多线程模型: 分发事务疑问 事务分发基本要求 MySQL 各版本并行复制策略

  • Mysql 的并行复制

    1.依据binlog和pos节点主从复制 一般主从复制,有三个线程参与,都是单线程:Binlog Dump(主) ...

  • MySQL的并行复制

    MySQL的主从复制延迟一直是受开发者最为关注的问题之一,MySQL从5.6版本开始追加了并行复制功能,目的就是为...

  • WriteSet并行复制

    author:sufei 源码版本:5.7.26 一、MySQL并行复制过程的发展 库间并发 理论依据: 一个数据...

  • MySQL的并行复制策略

    前面介绍的MySQL 的主从复制流程如下所示: 主备延迟的主要原因在于,master A 上产生 binlog 的...

  • MySQL开启 WriteSet并行复制

    # 从库需要执行stop slave;set global binlog_transaction_dependen...

  • 基于GTID的主从实践系列之④并行复制搭建及测试

    并行复制最早在5.6就搞出来了,是一个库级别的并行复制(slave_parallel_type可以有两个值:DAT...

  • mysql5.7.17并行复制bug复现

    背景 疑问 课前知识(并行复制-COMMIT_ORDER) 疑问1分析(这个bug一定会导致数据不一致吗) 疑问2...

  • MySQL 5.7 并行复制解决复制延迟问题

    一、缘由: 某天看到主从复制延时的告警有点频繁,就想着是不是彻底可以解决一下。 一般主从复制,有三个线程参与,都是...

网友评论

      本文标题:MySQL的并行复制

      本文链接:https://www.haomeiwen.com/subject/qsciertx.html