作者:百变精灵1980 | 来源:互联网 | 2023-10-15 20:07
MySQL45讲之备库并行复制策略-前言本文主要介绍MySQL备库的并行复制策略。为什么备库需要并行复制如果主库有大量更新操作,因为主库可以并发写入,而备库只能单线程执行的
前言
本文主要介绍 MySQL 备库的并行复制策略。
为什么备库需要并行复制
如果主库有大量更新操作,因为主库可以并发写入,而备库只能单线程执行的话,那么备库的同步延迟会不断累加,即备库越来越追不上主库。所以,后面有了备库的并行复制。
备库的并行复制模型:
coordinator 职责是分发 binlog 给工作线程,真正执行同步的是 worker。
按表分发策略
每个 worker 工作线程都对应一个表,coordinator 根据 binlog 内容将事务分发到不冲突的 worker 中并行执行,如果发生冲突,则等到不冲突的情况再分发到 worker 中执行。
以“数据库名 + 表名”为键,判断是否冲突:
-
如果待分发事务的键和 worker 存在键冲突数等于0,则选择空闲的 worker 执行;
-
如果待分发事务的键和 worker 存在键冲突数等于1,则选择冲突的 worker 执行;
-
如果待分发事务的键和 worker 存在键冲突数大于1,则等待直到前两个条件符合;
按行分发策略
和按表分发策略同理,不过是以“数据库名 + 表名 + 主键名 + 主键值”或者“数据库名 + 表名 + 唯一键名 + 唯一键值”为键来判断冲突,需要计算更多的键。
为什么还需要判断唯一键是否冲突?
因为并发执行时,执行时序不与原先相同,原先后执行的事务可能现在先执行,有可能会导致不符合唯一性约束,造成数据不一致。
组提交并行策略
MariaDB 提出的并行复制策略
MySQL 组提交的前提是组里面的事务是不冲突的,或者说并行执行不影响数据一致性的。组提交时,在 binlog 中记录 commit_id,那么在备库分发时,将同一个 commit_id 的事务分到不同的 worker 并行执行。
不过,这个方法存在一个缺陷。备库每次执行分发同一个 commit_id 下的事务到 worker 中执行,等都执行完之后,才可以分发下一个 commit_id 对应的事务。这样的话,备库并不是真正地在并行复制,并且,如果一个 commit_id 下的某个事务是大事务,那么将导致下一组执行的时间延后,即存在“短板效应”。
组提交优化策略
MySQL5.7 提出的并行复制策略,在 MariaDB 并行复制策略上进行了优化。
根据 MySQL 两阶段提交,只要处于 prepare 阶段的事务就可以并行执行。所以,下面情况下的事务都可以并行执行:
-
同时处于 prepare 的事务
-
处于 prepare 和 commit 之间的事务
write_set策略
在主库写入 binlog 之前,计算事务涉及的每一行的 hash 值,写入 binlog,这样在备库分发的时候就不需要解析 binlog 来判断,只需要判断两个事务是否有交集来判断是否可以并行,提交运行效率。
因为不需要解析 binlog 来获取信息,所以该方法下, binlog 采用 statement 和 row 格式都可以。
此外,还有 write_set_session 策略,它在 write_set 策略上加了一个约束,同一个线程先后执行的两个事务,在备库复制时不能并行。
参考