MySQL的并行复制策略

前面介绍的MySQL 的主从复制流程如下所示:

图片发自简书App

主备延迟的主要原因在于,master A 上产生 binlog 的速度大于slave B 处理 binlog 的速度。数据的积压就在于 sql_thread 处理的速度。在 MySQL 5.6 版本之前,只支持单线程复制。单线程的 binlog 复制,在高并发的场景下会出现严重的主从不一致。要解决这个问题,就需要将上面的 sql_thread 拆解成为多个线程处理。

图片发自简书App

上图中的 coordinate 就是本文开始的 sql_thread,具体执行 binlog 复制的是 Worker。生产上,Worker 的个数设置为 8-16 个比较合适(32核CPU),因为从库还需要可能还需要处理读的请求。

对于 coordinate 的分发策略,并不能是随机的,因为这样对于SQL 执行不同的顺序,可能会产生不同的结果。此时对于 coordinate 的分发策略要求如下:

不能造成更新覆盖,同一行的更新必须被分发到同一个Worker 中;

同一个事务不能被拆开,必须被分配到同一个Worker 中。

按表分发策略

按表分发的基本思路是,如果两个事务更新不同的表,就可以并行处理。此时因为在不同 Worker 处理时,也不会更新到同一行的数据。如果有跨表的事务,则需要 2 张表都需要考虑了。

图片发自简书App

从上图可以看出,每个 Worker 都对应一个 hash 表,用于保存当前 Worker 执行的 binlog 涉及的表。hash 表的 key 是 “库名+表名”,value 表示 Worker 中有多少个事务操作这个表。当事务执行完成后,其所涉及的表的计数会从hash 表中移除。上面 Worker_1 中的hash 表中 db1.t1:4 ,表示:Worker_1 中修改 db1.t1 表的事务数有 4 个。

假设 coordinate 读取一个事务 T (涉及 t1 和 t3的改动),此时分配规则如下:

Worker_1 中有事务在处理 t1 的改动,此时和 Worker_1 是冲突的,对于Worker_2 有在处理 t3 的改动,此时和Worker_2 也是冲突的;

当事务 T 和多于 1 个Worker 冲突时,coordinate 就进入等待状态;

此时如果 Worker_2 中执行完事务后,对应 t3 的计数就会减 1,此时事务 T 就只和 Worker_1 冲突了,此时就会将其加入到 Worker_1 的队列中;

coordinate 读取新事务 T2 继续执行 步骤 1 。

总结以上,coordinate 在分发事务的时候,会考虑以下冲突情况:

当没有 Worker 冲突的时候,会将其加入到空间的Worker 中去;

当有只有 1 个Worker 冲突的时候,会将其加入到冲突的Worker 中去;

当有多于 1 个Worker 冲突的时候,coordinate 会进入等待状态,直到冲突数 <= 1。

按行分发策略

按行分发的策略和按表分发的策略类似,但是在考虑Worker 冲突的时候对应的hash key 就是“库名+表名+唯一键的值”,原理类似,这里就不做过多的介绍了。这里需要注意的点是,按行进行冲突检测,其消耗的计算量还是比较大的。

MySQL5.6 的并行复制

MySQL 从 5.6 版本开始支持按库级别的并行复制。对于一个应用来说,如果我们按照业务分库,从应用的层面上面讲是提高了 binlog 的复制能力的。按库级别的并行相比按表和按行级别的,有以下 2 个优势:

构造 Worker 的 hash 表很快,因为库的个数不会太多,而且计算量也会减少;

不需要要求 binlog 的格式。

MariaDB 的并行复制

在之前介绍的 redo log 组提交时,有以下特点:

在一个组里提交的事务,一定不会修改同一行;

主库上面可以并行的事务,在从库上面也是可以并行的。

MariaDB 并行复制的实现上,操作流程如下:

在一个组里面提交的事务有一个相同的 commit_id,下一个组就是 commit_id + 1;

commit_id 直接写到 binlog 里面;

传到备库的时候,相同 commit_id 的事务会被分发到不同的 Worker 中执行;

这一组执行完成后,再去取下一组重复以上步骤。

从上面流程可以看出,下一个组提交的执行依赖上一个组提交的执行完成。此时如果上一个组提交中有大事务,就会影响下一个组提交的执行,容易造成阻塞。

MySQL5.7 的并行复制

MariaDB 在实现了并行复制能力之后,MySQL 也提供了类似的功能。由 slave-parallel-type 参数来控制并行复制的策略:

配置为 DATABASE,表示使用 MySQL 5.6 开始提供的按库并行复制的策略;

配置为 LOGICAL_CLICK,表示就是使用类似于 MariaDB 并行复制策略。

对于 LOGICAL_CLICK 这种策略,MySQL 5.7 对其做了优化。说优化之前,我们先看一下之前提到的“事务两阶段提交的细化流程”。

图片发自简书App

上面提到的 MariaDB 并行复制的核心是:一个组内,已经提交的事务是可以并行的。但是从上面流程可以看出,只要 redo log prepare (第一步)完成之后,事务之间就已经完成冲突检测了。因此 MySQL 5.7 的优化思想如下:

同时处于 prepare 阶段的事务是可以并行执行的;

处于 prepare 阶段的事务与处于 commit 状态的事务之间,也是可以并行执行的。

前面在 binlog 组提交的时候,介绍了下面 2 个参数:

binlog_group_commit_sync_delay 参数:表示延迟多少个微妙之后,再执行 fsync;

binlog_group_commit_sync_no_delay_count 参数:表示累计多少次之后,再执行 fsync。

上面 2 个参数是提高组提交里面的事务批量,简单的理解可以是:减慢主库的 binlog 写入,让备库能赶得上。

MySQL5.7.22 的并行复制

在 2018年4月发布的 5.7.22 版本里面,新增了基于 writeset 的并行复制。新增了

binlog-transaction-dependency-tracking,用来控制是否启用这个新策略,这个参数有以下 3 个可选值:

COMMIT_ORDER:就是前面提到的处于 prepare 和 commit 状态的 binlog 都可以被分发到 Worker 上面处理;

WRITESET:对于事务更新的每一行,都计算出一个 hash 值,组成集合 writeset。如果两个事务的 writeset 没有交集,说明事务没有操作相同的行,事务之间是可以并行的;

WRITESET_SESSION:是在 WRITESET 的基础上新增了一个约束,就是在主库上面同一个线程执行的 2 个事务的执行顺序,在从库上面也需要保证顺序性。

可以看出,MySQL 5.7.22 提出的并行复制策略和之前说的按表、按行的并行复制原理类似。另外其还有一些优化点:

writeset 是在主库上面生成后直接写到 binlog 里面的,这样在备库执行时,就需要解析 binlog 的内容,节省了很多计算量;

不需要把整个事务的 binlog 都扫描一遍后,才决定分发到哪个 Worker,更节省内存;

由于备库的分发策略不依赖于 binlog 的内容,因此对 binlog 的格式没有要求。

当然上面所说的并行复制的前提都是,没有外键约束,所有表都有主键的场景。如果不满足,则会退化成单线程的模式。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容