0
0
0
0
专栏/.../

DM 数据旅程 02:分库分表悲观协调——02Lock -> Resolve Lock

 okenJiang  发表于  2023-01-03
原创迁移

一、概述

介绍了与悲观协调有关的各个数据结构之后,接下来将介绍一个 DM 系统从接受到第一条分表 DDL 开始,到所有该 DDL 对应的 Lock resolved 的全过程。

本节内容皆参考 DM v6.0,对现在而言,有可能已过时,欢迎大家提出意见~

二、Overview

假设现在起了 master 和两个 Worker,两个 Worker 分别绑定两个 Source(s1,s2),每个 Source 有两个分表(t1,t2),这四个表会 route 到一个 target table(tarTbl)中。在 DDL 到来之前,两个 worker 会创建好 ShardingGroupKeeper,里面只有一个 target table,两个 source table。

两个 Worker 先后收到两个 Source 四个分表的同一条 DDL,表示为:

  • DDL1:表示对 s1.t1 的 DDL。
  • DDL2:表示对 s2.t1 的 DDL。
  • DDL3:表示对 s1.t2 的 DDL。
  • DDL4:表示对 s2.t2 的 DDL。

三、具体过程

本小节 worker 对 DDL 的处理从 handleQueryEventPessimistic 开始,如果不知道在此之前的 DDL 做过哪些处理,请期待后续文章😁

接下来将对上图中的步骤一一介绍

Step 1

  1. worker1 收到来自 source1 的 DDL1,会直接 TrySync,这里返回了一大堆的参数,其实有用的就只是 synced,简单来说,里面只做了一件事:AddItem。下面详细介绍一下 TrySync

本节,假设该 DDL 不是 CreateTableStmt,如果是的话,也很简单,每次都是 remain <=0,synced = true,但是只有第一次发送该 create table 的 worker 会 syncDDL。

TrySync

想要知道 worker 在悲观协调的时候做了什么,必须要搞懂 TrySync 是怎么运作的。在此之前,我们来重新理解一下 ShardingGroupKeeper:

单独拿出一个 ShardingGroup 举例(颜色代表 DDL 的种类):

Example

worker 收到了以下 DDL

  • 依次收到了 table1 橙色、黄色、绿色三条 DDL
  • 收到了 table2 橙色
  • 这个时候 activeIdx = 0remain = 1,因为只有 table3 没有收到 active DDL 了

  • 如果在这个时候收到了 table3 橙色 DDL,remain = 0,处理了这条 DDL 之后,active ++

image.png

  • 如果这个时候收到 table2 绿色 DDL,则会报错,悲观协调要求同一个 source table 中 DDL 必须有序

  • 如果 group 中所有的 DDL 都 resolved 了。则会重置一下 meta

总结:AddItem 就是上面图中把 DDLItem 放进 ShardingSequence 的过程

Step 2 与 Step 1 相同

Step 3

由于 tarTbl 只有两个 source table:s1.t1 和 s1.t2,这时 TrySync 后,synced = true,说明该 worker ready

Step 4

worker1

Master

  • watchInfoPut:成功监听到了
  • handleInfoPut:master 也开始 TrySync,master 的 TrySync 相比 worker 中的要简单很多,每一个 Info 直接相当于该 source/worker 已 ready,所以直接统计是否所有 ready 即可
  • 由于这里是第一个 worker 发 info 给 master,所以需要新建 Lock,新建 Lock 过程中会获取该 task 所有的 source,并存到 lock 中,这样就知道还有多少 source 没 ready。显然还有 source2 没 ready。
  • 继续等待

Step 5 与 Step 3 相同

Step 6

  • 前面与 Step 4 相同,但是这时所有 source 都 ready 了,synced = true

Step 7

master

Worker1

Step 8

Step 9

Worker1

Step 10

Master

Worker2

  • 接受到了 no exec(skip) 的 operation,和 Step 7 类似,但是在 syncDDL 的时候会被 skip

Step 11 和 Step 9 相同

四、总结

本节介绍了在悲观协调过程中,遇到第一条 DDL 语句,生成 Lock,到收到所有 DDL 语句,Lock 解除的过程。

经过本节的学习,我们已经完全学会了 DM 悲观协调的过程。是不是也没那么复杂😏,但是在这个过程中,我们只知道 DDL 的处理方式,这个过程中的 DML 会怎么办呢?下一章揭晓。

五、疑似 bug

  1. initShardingGroups 中对 ShardingGroup.sources 进行了初始化,这里包含了该 targetTable 对应的所有 sourceTables
  2. TrySync 的时候,却使用第一个 sourceTable[0],来标记所有的 DDL[],如果 len(DDL[]) != 1,则 remain 永远不可能为 0。因为 sourceTables 来源于 ddlInfo。而 DDLInfo 只存了第一条 ddl 的 ddlInfo,实际上对于每一个 Split 之后的 DDL,都会 genDDLInfo
  3. 但是奇怪的是,代码中标注了不支持 multi-table DDL,这个 error 在 pessimist/optimist mode 中都用到了。但是在现在看 pessimist 代码中,又看到其为 multi-table DDL 实现了部分相关逻辑。。。有毒
  4. 比如:
  • https://github.com/pingcap/tiflow/blob/release-6.0/dm/syncer/syncer.go#L2957-L2960
  • https://github.com/pingcap/tiflow/blob/release-6.0/dm/syncer/sharding-meta/shardmeta.go#L35
  • 。。。

0
0
0
0

版权声明:本文为 TiDB 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论
暂无评论