深入浅出 SQL Server CDC 数据同步

这篇具有很好参考价值的文章主要介绍了深入浅出 SQL Server CDC 数据同步。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

SQL Server 是一款老牌关系型数据库,自 1988 年由 Microsoft、Sybase 和 Ashton-Tate 三家公司共同推出,不断迭代更新至今,拥有相当广泛的用户群体。

如今,我们提到 SQL Server 通常指 Microsoft SQL Server 2000 之后的版本。

SQL Server 2008 是一个里程碑版本,加入了大量新特性,包括 新的语法更丰富的类型 以及本文所提及的 CDC 能力,这个能力让数据从 SQL Server 实时同步到外部更加方便。

本文将介绍 CloudCanal 在新版本中对于 SQL Server 数据同步更进一步的优化和实践。

SQL Server CDC 长什么样?

原始日志

常见的数据库往往存在以下两种日志

  • redo 日志
    • 记录数据的正向变更,简单来说,事务的 commit 通常先记录在这个文件,再返回应用程序成功,可确保数据 持久性
  • undo 日志
    • 用于保证事务的 原子性,如执行 rollback 命令即反向执行 undo 日志中内容以达成数据回滚

一条 DML 语句写入数据库流程如下

深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

  • 大部分关系型数据库中,一个或多个变更会被隐式或显式包装成一个事务
  • 事务开始,数据库引擎定位到数据行所在的 文件位置 并根据已有的数据生成 前镜像后镜像
  • 后镜像 数据记录到 redo 日志中,前镜像 数据记录到 undo 日志中
  • 事务提交后,日志提交位点(检查点)向前推进,已提交的日志内容即可能被覆盖或者释放

SQL Server redo/undo 日志采用了 ldf 格式 ,文件循环使用。

深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

  • ldf 日志文件由多个 VLF(逻辑日志) 组合在一起,这些 VLF 首尾相连形成完整的数据库日志记录
  • ldf 在逻辑日志末端到达物理日志文件末端时,新的日志记录将回到物理日志文件开始,复写旧的数据

ldf 文件即 CDC 所分析的增量日志文件。

启用 CDC

在数据库上执行 exec [console].sys.sp_cdc_enable_db 命令为 console 数据库启用 CDC 功能,这个语句实际上会创建两个作业: cdc.console_capture , cdc.console_cleanup

使用 exec sp_cdc_help_jobs 命令可查看这两个作业详细信息。
深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

  • cdc.console_capture
    • 负责分析 ldf 日志 并解析 console 数据库事件,再将其写入到 CDC 表中
    • 间隔 5 秒钟执行一次扫描,每次扫描 10 轮,每轮扫描最多 500 个事务
  • cdc.console_cleanup
    • 负责定期清理 CDC 表中较老的数据
    • 默认保留 3 天 CDC 日志数据(4320秒)

开启 CDC 功能后,SQL Server 数据库会多出一个名称为 cdc 的 schema,里面会多出下列这些表。

深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

  • change_tables
    • 记录每一个启用了 CDC 的 源表 及其对应的 捕获表
  • captured_columns
    • 记录对应 捕获表 中每个列的信息
  • index_columns
    • 记录 源表 含有的主键信息(如果有)
  • lsn_time_mapping
    • 记录每个事务的开始/结束时间及 LSN 位置信息
  • ddl_history
    • 记录源表发生的 增/减列 对应的 DDL 信息,除此之外的 DDL 都不会被记录

有了上述准备动作和信息,即可开始对原始表开启 change data capture(CDC),即增量数据捕获了。

捕获表变更

有如下 源表

create table [dbo].[test_table] (
  [id] [bigint] NOT NULL primary key,
  [test] [nchar](10) NULL
)

执行下列命令即可为它启用 CDC

exec [console].[sys].[sp_cdc_enable_table]
    @source_schema = [dbo],
    @source_name = [test_table],
    @role_name = NULL,
    @capture_instance = [dbo_test_table], -- 可选项
    @supports_net_changes = 0;

cdc schema 下多出一个名为 dbo_test_table_CT 的表,即 捕获表

  • 源表 [dbo].[test_table] 做若干 DML 操作,通常是 5 秒内就可在捕获表中看到变更记录
  • 源表 做一些 增/减 列 操作,对应的 DDL 会出现在 ddl_history 表中

深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

其他表也可通过类似设置,获取到相应的增量变更。整个机制看上去相当直观和简单。

挑战是什么?

难点1:DDL 同步困难

CDC 捕获表只反馈数据的变化,无 DDL 信息

DDL 需额外获取即和 DML 的顺序关系要额外处理
深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

解决这个问题,需要通过执行以下的 SQL 将 DDL 和 DML 事件混合到一起并保证顺序,但是实际使用中会面临严重的性能问题。

select * from (
	select __$start_lsn lsn,__$operation oper,__$update_mask mask, null ddl ,id data_id,test data_test 
	from [console].[cdc].[dbo_test_table_CT]
	union
	select ddl_lsn lsn, -1 oper,null mask,  ddl_command ddl ,null data_id,null data_test 
	from [console].[cdc].[ddl_history]
) t order by lsn

难点2:无法获取新增列数据

CDC 捕获表的结构并不会随着 DDL 事件的发生而变化,这意味着无法获取新增列的数据
深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

难点3:数据库限制

使用 CDC 功能本身也会产生一些硬性的限制,大致可以分为两类

硬性限制

  • 已经启用 CDC 捕获的源表上不能执行 truncate table 语句,执行即报错

  • CDC 捕获表本质上也是一个普通的表,大量订阅会导致整库表的数量扩大

  • 依赖 SQL Server 代理,如没启动或作业运行失败,捕获表中不会有任何新数据写入

  • 一张表只能创建 2 张对应的 CDC 捕获表,即无法做超过 2 个以上的增量订阅

  • 一张表的 CDC 捕获只能设置启动和禁止,即不能通过重建 CDC 并指定 LSN 来获取新数据

软性限制

  • CDC 捕获表中的数据存留时间默认 3 天

  • 在插入或更新超大字段时默认 CDC 只会处理最大 64KB 个字节的数据

    • 数据内容如果超过这个限制会导致 CDC 捕获任务报错并停止工作
    • 受影响的类型有 7 个:textntextvarchar(max)nvarchar(max)varbinary(max)xmlimage

CloudCanal 的解决方法

CloudCanal SQL Server 增量消费基础处理模型如下所述,保证单个表的数据变更顺序,满足大部分场景

深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

  • 根据 change_tables 表确定一个工作队列
  • 确定起始位点,对于捕获表的增量数据扫描从起始位点开始
  • 并发处理工作队列上的事件
  • 每个 Worker 会根据起始 LSN 扫描自身要处理的 CDC 捕获表
  • 每个 Worker 扫描都会维护自身的 LSN 进度

解决难点1:DML/DDL重排序

CDC 捕获表中的每一条记录都有一个 LSN 信息,ddl_history 表也有 LSN 信息。因此可以借助 插值 的思想将 DDL 事件插入到正常的 DML 事件序列中去,原理如下图:

深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

  1. ddl_history 表进行预查询,获取到的 DDL 事件在稍后的处理中会进行位点比对处理
  2. 查询 dbo_test_table_CT 数据捕获表
  3. 处理每一条的捕获表的数据时检测 DDL 事件是否可以被插入
  4. 形成完整的事件流

解决难点2:反查补充缺失数据

SQL Server CDC 捕获表最多只能创建 2 张是硬性限制,但刚好能解决这个问题,在 DDL 发生后创建第二个 CDC 捕获表可以感知到 DDL 对数据的变化

深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

  1. 创建第一个 CDC 捕获表 dbo_test_table_1_CT
  2. 在两次数据插入的中间增加一个新的列
  3. 创建第二个 CDC 捕获表 dbo_test_table_2_CT
  4. 在插入一条新数据

通过上图可看到 dbo_test_table_2_CT 相比 dbo_test_table_1_CT 已经可以感知到新增的列数据

遗憾的是 DDL 发生后到第二个 CDC 捕获表创建出来之前这中间的数据仍然是缺失的

上面的例子如下图所示(灰色的 Event 表示事件或者数据有缺损)

深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

以 DDL 发生的 LSN 为分界点

  • 在 DDL 发生之前 dbo_test_table_1_CT 表中的数据是完全可信的
  • 在 DDL 发生之后由于 dbo_test_table_1_CT 表中并没有新列字段,因此它的数据是残缺的,不能完全信任
  • dbo_test_table_2_CT 是由于在 DDL 发生后才被创建出来,因此相比较 dbo_test_table_1_CT 它的数据是缺失的
  • 此外 dbo_test_table_1_CTdbo_test_table_2_CT 之间还存在一个盲区导致这个 INSERT 事件两个表都不可信

CloudCanal 解决办法是在此基础上将两张表都缺损的位点 反向使用 PK 从源表中补齐 的方式解决这个问题(上图中深灰色部分)

有一个极端情况是在第二张 CDC 捕获表创建过程中发生了新的 DDL ,这会导致新创建的捕获表也不可靠,因此需要重新创建第二个 CDC 捕获表,并且扩大中间需要反查补齐的数据范围(下图中深灰色部分)

深入浅出 SQL Server CDC 数据同步,CloudCanal,数据库,microsoft,sqlserver

CloudCanal 正是基于上述一系列机制才解决了 DDL 事件导致无法获取增量数据的难题

解决难点3:提供专业优化方案

对于硬性限制,CloudCanal 没有正面解决的方案,而是后续提供更多样的方式(如 trigger,定时增量扫描,新版本SQL Server CDC方案 等)进行补充。

软性限制,可通过以下方式优化

  • 通过以下命令中的 retention 参数来设置 CDC 捕获表中的数据存留时间

    exec console.sys.sp_cdc_change_job 
        @job_type = 'cleanup',
        @retention=4320 -- 单位:秒
    
  • 通过以下命令调整 CDC 处理的最大数据字节

    exec sp_configure 'show advanced options', 1 ;   
    reconfigure;
    exec sp_configure 'max text repl size', -1; -- -1 表示不限制
    reconfigure;
    

总结

本文简单介绍了 SQL Server CDC 技术,然后基于此能力,CloudCanal 是如何实现稳定的增量 DML + DDL 同步, 并且解决了其中遇到的难题。文章来源地址https://www.toymoban.com/news/detail-532019.html

到了这里,关于深入浅出 SQL Server CDC 数据同步的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 大数据-玩转数据-深入浅出K8S

    Docker 是一个开源的、轻量级的容器引擎,和 VMware 虚拟机相比,Docker 使用容器承载应用程序,而不使用操作系统,所以它的开销很少,性能很高。但是,Docker 对应用程序的隔离不如虚拟机彻底,所以它并不能完全取代 VMware。 在传统的开发过程中(我之前的开发过程),以

    2024年02月04日
    浏览(55)
  • 深入浅出堆—C语言版【数据结构】

    二叉树概念博客 :http://t.csdn.cn/XIW84 目录 1. 了解堆 1.1 堆的概念 1.2 堆的性质: 1.3 堆的结构图片 1.3.1 小堆 1.3.2 大堆 2. 堆的实现 2.1 插入数据进堆 2.2 向上调整函数 2.3 堆的删除 2.4 向下调整 3. 堆的应用 3.1 建堆(两种方式) 3.1.1 建堆方式1 3.1.2 建堆方式2 3.2 堆排序  3.3 堆的

    2024年02月04日
    浏览(50)
  • 【数据结构与算法篇】深入浅出——二叉树(详解)

    ​👻内容专栏:《数据结构与算法专栏》 🐨本文概括: 二叉树是一种常见的数据结构,它在计算机科学中广泛应用。本博客将介绍什么是二叉树、二叉树的顺序与链式结构以及它的基本操作,帮助读者理解和运用这一重要概念。 🐼本文作者: 花 蝶 🐸发布时间:2023.6.5

    2024年02月08日
    浏览(50)
  • 深入浅出二叉树— C语言版【数据结构】

    目录 ​编辑 1.树概念及结构 1.1树的概念 1.2 树的相关概念 ​1.3 树的表示 2.二叉树概念及结构   2.1概念 2.2 特殊的二叉树 2.3 二叉树的性质  2.4 简单二叉树题目练习  2.5 二叉树的存储结构 2.5.1 顺序存储——堆 2.5.2 链式存储 树是一种 非线性的数据结构 ,它是由n(n=0)个有

    2024年02月03日
    浏览(78)
  • 【大数据】深入浅出 Apache Flink:架构、案例和优势

    Apache Flink 是一个强大的开源流处理框架,近年来在大数据社区大受欢迎。它允许用户实时处理和分析大量流式数据,使其成为 欺诈检测 、 股市分析 和 机器学习 等现代应用的理想选择。 在本文中,我们将详细介绍什么是 Apache Flink 以及如何使用它来为您的业务带来益处。

    2024年01月17日
    浏览(49)
  • 探索数据的奥秘:一份深入浅出的数据分析入门指南

    书籍推荐 入门读物 深入浅出数据分析 啤酒与尿布 数据之美 数学之美 数据分析 Scipy and Numpy Python for Data Analysis Bad Data Handbook 集体智慧编程 Machine Learning in Action 机器学习实战 Building Machine Learning Systems with Python 数据挖掘导论 Machine Learning for Hackers 专业读物 Introduction to Semi-Su

    2024年01月21日
    浏览(46)
  • 深入浅出带你玩转栈与队列——【数据结构】

    W...Y的主页 😊 代码仓库分享 💕 目录 1.栈 1.1栈的概念及结构 1.2栈的结构特征图  ​编辑 1.3栈的实现 1.3.1栈的初始化 1.3.2进栈 1.3.3出栈 1.3.4销毁内存 1.3.5判断栈是否为空 1.3.5栈底元素的读取 1.3.6栈中大小 1.4栈实现所有接口 2.队列 2.1队列的概念 2.2队列的结构   2.3队列的实

    2024年02月11日
    浏览(62)
  • 【数据结构与算法】深入浅出:单链表的实现和应用

      🌱博客主页:青竹雾色间. 😘博客制作不易欢迎各位👍点赞+⭐收藏+➕关注  ✨ 人生如寄,多忧何为  ✨ 目录 前言 单链表的基本概念 节点 头节点 尾节点 单链表的基本操作 创建单链表 头插法: 尾插法: 插入(增)操作  删除(删)操作: 查找(查)操作: 修改(改

    2024年02月08日
    浏览(75)
  • 【深入浅出 Spring Security(四)】登录用户数据的获取,超详细的源码分析

    在【深入浅出Spring Security(一)】Spring Security的整体架构 中叙述过一个SecurityContextHolder 这个类。说在处理请求时,Spring Security 会先从 Session 中取出用户登录数据,保存到 SecurityContextHolder 中,然后在请求处理完毕后,又会拿 SecurityContextHolder 中的数据保存到 Session 中,然后再

    2024年02月07日
    浏览(49)
  • 数据界的达克摩斯之剑----深入浅出带你理解网络爬虫(Forth)

    目录 3.爬虫身份识别 4.用户爬虫的例子 4.1 开源爬虫 网络爬虫的组成 控制器 解析器 资源库 网络爬虫通过使用http请求的用户代理(User Agent)字段来向网络服务器表明他们的身份。网络管理员则通过检查网络服务器的日志,使用用户代理字段来辨认哪一个爬虫曾经访问过以及

    2024年03月15日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包