DM 分库分表 DDL “悲观协调” 模式介绍丨TiDB 工具分享

2024-04-08 02:08

本文主要是介绍DM 分库分表 DDL “悲观协调” 模式介绍丨TiDB 工具分享,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

TiDB 作为分库分表方案的一个 “终结者”,获得了许多用户的青睐。在切换到 TiDB 之后,用户告别了分库分表查询和运维带来的复杂度。但是在从分库分表方案切换到 TiDB 的过程中,这个复杂度转移到了数据迁移流程里。TiDB DM 工具为用户提供了分库分表合并迁移功能,在数据迁移的过程中,支持将分表 DML 事件合并迁移,并一定程度支持上游分表进行 DDL 变更。

本文以及后续文章主要介绍分库分表合并迁移时,各分表 DDL 变更的协调。DM 的分库分表 DDL 协调可配置为 “悲观协调” 和 “乐观协调” ,本文主要介绍 TiDB DM 分库分表 DDL 协调的 “悲观协调” 模式。后续文章会介绍 “乐观协调” 模式。

分库分表 DDL 的问题(简略版)

本节首先以一个例子粗略介绍分库分表 DDL 对数据迁移的影响,然后就这个问题给出更加正式的定义。

假设在两个上游有两个分表 t1、t2,下游表为 t。

t1 接下来的同步事件是 INSERT (3,3),t2 接下来的同步事件是 DROP COLUMN c2。如果 DROP COLUMN c2 先被同步到下游,在同步到 INSERT (3,3) 时就会因为缺少 c2 列而报错。
因此我们要对 DDL 同步事件进行特殊处理。

分库分表合并迁移的定义

接下来我们尝试使用更正式一点的语言来描述这个问题,从而引出如何正确解决这个问题。

从用户的角度来讲,数据库的用途主要的是查询,在分库分表合并前后,查询的结果应该是相同的(不考虑 LIMIT 等算子以及不确定性查询)。也就是说,各分表查询结果的并集应当等于迁移后的查询结果。容易得到一个满足此要求的充分条件:各分表数据的并集应当等于迁移后的表数据。考虑到同步延迟的影响,也就是当前时刻下游表的数据等于各分表在过去某时刻数据的并集。
对于这个定义而言,数据迁移就是让各分表的同步时刻不断向前推进。如果在同步某事件前,下游表与各分表满足定义,那么我们将一个分表的同步事件以相同影响的方式应用到下游,就将该分表的同步时刻正确地推进了。

分库分表 DDL 的问题(正式版)

从上面的定义来看,DDL 会造成两个方面的问题。

首先是 DDL 可能会变更表结构。参照之前的例子,如果 t1、t2 都有 DROP COLUMN c2 事件,DM 先同步到了 t2 的该事件,而同步事件需要以相同影响的方式应用到下游,我们应该只将下游 t2 对应的数据 DROP COLUMN。显然下游 t1、t2 的数据共享一个表结构,无法完成这个操作。因此 t2 的该事件暂时不能被同步。
另一个问题是,部分 DDL 即使不影响表结构,也会产生对数据产生影响。例如 ALTER TABLE DROP COLUMN c, ADD COLUMN c DEFAULT xx,会将一个分表的 c 列全部修改为 xx。目前 DM 的实现同样无法将这个事件以相同影响的方式应用到下游

解决方法

对于上述 DDL 引入的问题并基于前文对于同步正确性的定义,我们可以得到一个满足要求的充分条件:当某分表出现 DDL 同步事件时,我们将其同步暂停;直到所有分表都出现该 DDL 同步事件时,我们将 DDL 应用到下游并恢复所有分表的同步。此时我们可以保证下游表的 DDL 产生的影响等于所有分表都进行了 DDL(不考虑非确定性 DDL,例如 DDL 新增列默认值为 current_timestamp)。

悲观协调例子

我们仍然以两张表 t1、t2 的合并迁移为例,观察 binlog 同步进度

左图中,当分表 t1 遇到 DDL 时,t2 同步事件还没有到这条 DDL,因此 t1 同步应当被暂停。当进展到右图时,t1、t2 分表都出现了相同的 DDL,因此此时可以将这条 DDL 应用到下游并恢复 t1、t2 的同步。\

在某些情况下,t1、t2 可能位于一个 binlog 流之中,因此上图中看似独立的流的暂停与恢复,实际实现为在同一个 binlog 流中跳过事件及回滚同步位置。

如上图,我们需要在事件 1、2、4、5、6 之后同步事件 3,因此在 binlog 流中首次遇到事件 3 时跳过,并在事件 6 完成之后重新从事件 3 开始同步,并跳过已经同步的 4、5、6 事件。

悲观协调模式限制

可以看到这种协调模式解决方法有如下的限制:

  • 出现 DDL 同步事件时分表会暂停,会导致同步延迟增加。这可能会导致恢复同步时,上游 binlog 已经被清理
  • 不支持只变更部分分表以进行灰度测试时的场景。灰度期间其余分表的同步会暂停。此外如果灰度测试结果是回滚时,无法恢复同步
  • 要求所有分表以相同的顺序出现 DDL 同步事件
  1. 如果分表由于误操作而进入 DDL 不一致的状态,修复操作较为复杂
  2. 对于 DM 的使用者而言,可能无法控制上游 DDL 的发起从而无法满足条件\

因为悲观协调模式的种种限制,DM 也提供了新的乐观协调模式,我们将在后续的文章中具体介绍,希望大家能够在深入了解两种协调模式的原理和使用限制后,根据场景选择合适的模式进行分库分表的合并迁移。

这篇关于DM 分库分表 DDL “悲观协调” 模式介绍丨TiDB 工具分享的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/884295

相关文章

Java嵌套for循环优化方案分享

《Java嵌套for循环优化方案分享》介绍了Java中嵌套for循环的优化方法,包括减少循环次数、合并循环、使用更高效的数据结构、并行处理、预处理和缓存、算法优化、尽量减少对象创建以及本地变量优化,通... 目录Java 嵌套 for 循环优化方案1. 减少循环次数2. 合并循环3. 使用更高效的数据结构4

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

基于.NET编写工具类解决JSON乱码问题

《基于.NET编写工具类解决JSON乱码问题》在开发过程中,我们经常会遇到JSON数据处理的问题,尤其是在数据传输和解析过程中,很容易出现编码错误导致的乱码问题,下面我们就来编写一个.NET工具类来解... 目录问题背景核心原理工具类实现使用示例总结在开发过程中,我们经常会遇到jsON数据处理的问题,尤其是

Java中有什么工具可以进行代码反编译详解

《Java中有什么工具可以进行代码反编译详解》:本文主要介绍Java中有什么工具可以进行代码反编译的相关资,料,包括JD-GUI、CFR、Procyon、Fernflower、Javap、Byte... 目录1.JD-GUI2.CFR3.Procyon Decompiler4.Fernflower5.Jav

使用Python创建一个能够筛选文件的PDF合并工具

《使用Python创建一个能够筛选文件的PDF合并工具》这篇文章主要为大家详细介绍了如何使用Python创建一个能够筛选文件的PDF合并工具,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录背景主要功能全部代码代码解析1. 初始化 wx.Frame 窗口2. 创建工具栏3. 创建布局和界面控件4

Docker部署Jenkins持续集成(CI)工具的实现

《Docker部署Jenkins持续集成(CI)工具的实现》Jenkins是一个流行的开源自动化工具,广泛应用于持续集成(CI)和持续交付(CD)的环境中,本文介绍了使用Docker部署Jenkins... 目录前言一、准备工作二、设置变量和目录结构三、配置 docker 权限和网络四、启动 Jenkins

Python中常用的四种取整方式分享

《Python中常用的四种取整方式分享》在数据处理和数值计算中,取整操作是非常常见的需求,Python提供了多种取整方式,本文为大家整理了四种常用的方法,希望对大家有所帮助... 目录引言向零取整(Truncate)向下取整(Floor)向上取整(Ceil)四舍五入(Round)四种取整方式的对比综合示例应

MobaXterm远程登录工具功能与应用小结

《MobaXterm远程登录工具功能与应用小结》MobaXterm是一款功能强大的远程终端软件,主要支持SSH登录,拥有多种远程协议,实现跨平台访问,它包括多会话管理、本地命令行执行、图形化界面集成和... 目录1. 远程终端软件概述1.1 远程终端软件的定义与用途1.2 远程终端软件的关键特性2. 支持的

Java数字转换工具类NumberUtil的使用

《Java数字转换工具类NumberUtil的使用》NumberUtil是一个功能强大的Java工具类,用于处理数字的各种操作,包括数值运算、格式化、随机数生成和数值判断,下面就来介绍一下Number... 目录一、NumberUtil类概述二、主要功能介绍1. 数值运算2. 格式化3. 数值判断4. 随机

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.