变更数据捕获(CDC)
从广泛意义上说,全球许多企业每天都需要通过频繁的数据批量处理与加载,来定期将数据从一个数据库迁移到另一个数据库(或数据仓库)。这类定期批量加载的工作,往往既耗费时间,又会消耗原始系统的大量处理能力。因此,管理员只能在业务运行的间歇期间运行数据的批量传输与复制作业,否则会产生严重的效率影响。而显然,这与24x7的不间断业务需求是背道而驰的。
近年来,变更数据捕获(Change Data Capture,CDC)已成为了在高速数据流通环境中,各种关系型数据库、云端数据库、以及数据仓库之间,进行低延迟、高可靠性且可扩展式数据复制的理想化解决方案。
什么是变更数据捕获?
CDC是指从源数据库捕获到数据和数据结构(也称为模式)的增量变更,近乎实时地将这些变更,传播到其他数据库或应用程序之处。通过这种方式,CDC能够向数据仓库提供高效、低延迟的数据传输,以便信息被及时转换并交付给专供分析的应用程序。
在数据不断变化,且无法中断与在线数据库连接的情况下,对于各种时间敏感(time-sensitive)类信息的复制,往往也是云端迁移的重要组成部分。与批量复制相比,变更数据的捕获通常具有如下三项基本优势:
- CDC通过仅发送增量的变更,来降低通过网络传输数据的成本。
- CDC可以帮助用户根据最新的数据做出更快、更准确的决策。例如,CDC会将事务直接传输到专供分析的应用上。
- CDC最大限度地减少了对于生产环境网络流量的干扰。
变更数据捕获的方法
目前,业界有多种CDC方法,可用于跟踪和传输变更的数据,您可以根据应用程序的实际要求,及其对于性能下降的容忍度,从中进行选取。下面,我将向您介绍四种不同的CDC方法所涉及到的技术、工作原理、以及它们各自的优缺点。
时间戳或版本号跟踪(Delete 操作不友好)
数据库设计者可以在需要跟踪的数据表中,设定某一列来代表最后被修改的时间戳或版本号。例如,我们通常可以将这些列命名为:LAST_UPDATE、DATE_MODIFIED、以及VERSION_NUMBER等。那些在上一次数据捕获之后,增加了时间戳的任何行,都将被视为发生了修改。而在基于版本号的跟踪方法中,变更一旦发生,所有具有最新版本号的数据,都被视为发生了修改。
在实际应用中,您可以结合版本和时间戳两个维度,来跟踪数据库表中的数据。例如,您可以设定一条逻辑--“捕获自2021年6月22日以来,相对于3.4版发生了变更的所有数据”。
优点:
- 简单易懂。
- 数据库设计者可以自定义应用程序的逻辑构建。
- 不需要任何外部的工具。
缺点:
- 给数据库增加了额外的开销。
- 需要额外的CPU资源,来扫描表中的数据变更,并需要预留资源,以确保 LAST_UPDATE列能够可靠地追踪所有资源表。
- 被删除的行不会存在于LAST_UPDATE中。如果没有其他脚本来跟踪此类删除的话,DML语句(例如“DELETE”)将不会被传递到目标数据库处。
- 容易出错,并可能导致数据出现一致性问题。
表的差异与增量(大数据量不友好)
这种CDC方法使用诸如:表增量(table delta)之类的实用程序,或tablediff,去比较两个表中的数据,以发现不匹配的行。据此,您可以使用其他的脚本,将源表的差异同步到目标表上。
虽然该方法在管理已删除行的方面,比时间戳CDC的效果更好,但是它在发现差异时,所需要的CPU资源较为显著。而且此类开销会随着数据数量的增加,而呈线性增加。此外,针对源数据库或生产环境的分析查询,也可能会降低应用本身的性能。对此,您可以定期将数据库导出至暂存环境中进行比较。不过,随着数据量的增加,此类传输的成本也会呈指数级增长。
表差异的另一个问题是,它无法捕获数据的临时性变更。例如,假设有人更新了某个字段,但随后又将其变更回了原始值。那么,如果您只是运行一个简单比较的话,将无法捕获到这个变更事件。而由于diff方法本身存在着延迟,因此也无法实时执行。
优点:
- 可使用各种原生的SQL脚本,来获取变更数据的准确视图。
缺点:
- 由于此方法会用到数据源的三个副本:原始数据、先前快照和当前快照,因此整体存储需求会有所增加。
- 在那些具有繁重事务负载的应用程序中,无法得到很好的扩展。
注意:表差异和时间戳CDC方法,都不适用于真实的生产环境。因此对于大型数据集,我建议您使用如下两种CDC方法。其实,基于触发器和事务日志的变更数据跟踪方法,只是出于相同目的的两种不同的服务方式。
基于触发器的CDC(增加了触发器的开销)

- 我们需要为参与数据复制的每个表,创建三个触发器,当数据记录发生如下特定事件时,则会触发相应的操作:
- 将新的记录插入数据表时,触发的是INSERT触发器。
- 数据记录发生变更时,触发的是UPDATE触发器。
- 数据记录被删除时,触发的是DELETE触发器。
- “事件历史”的影子表被存储在数据库本身,并由各种状态改变事件的序列所组成。
- 每当对象的状态发生变化时,新的事件都会被附加到该序列中。据此,有关变更记录的信息,也会被转移到“事件历史”的影子表中。
- 最后,根据历史表中的各个事件,变更会被传输到目标数据库中。
下面展示了一个简单的历史表:

由于源数据库中的每个表都需要一个触发器,因此在有变更发生时,在操作表上运行触发器的开销也会随之增加。不过,由于基于触发器的CDC是工作在SQL级别上的,因此许多用户会趋向于使用该方法。
优点:
- 非常可靠且详尽。
- 影子表可以提供所有事务的不可变详细日志。
缺点:
- 每次插入、更新或删除数据行时,都需要对数据库进行多次写入,此举降低了数据库的性能。
DBA和数据工程师应当持续关注并测试,那些被添加到生产环境中的各种触发器的性能,进而决定是否可以容忍此类额外产生的开销。
事务日志CDC (日志文件读取不友好)

众所周知,数据库虽然主要会将事务日志用于备份和恢复目的,但它们也可被用于将变更复制到目标数据库或数据湖中。而在基于事务日志的CDC系统中,数据流不会被持久性存储。它们会使用Kafka去捕获变更,并将变更推送到目标数据库中。
可见,基于事务日志的CDC和基于触发器的CDC之间的主要区别在于,每个变更都将进入由数据库引擎所生成的事务日志中。也就是说,数据库引擎会使用本机事务日志(也称为重做日志),来存储所有数据库的事件,以便在发生故障时,可以恢复数据库。它们无需执行任何应用程序级别的变更,或扫描影子表。因此,与基于触发器的CDC相比,从事务日志中恢复数据虽然更为复杂,但是会更加可行。
优点:
- 由于每个事务都不需要额外的查询,因此它对生产环境中的数据库系统的影响最小。
- 无需变更生产环境中数据库系统的架构,或添加额外的数据表。
缺点:
- 由于大多数数据库并不记录它们的事务日志格式,也不会在新的版本中公布对其实施的变更,因此DBA解析数据库的内部日志格式会较为困难。DBA有时需要在数据库的每个新版本中,去解析变更数据库的日志逻辑。
- 由于日志文件通常会被数据库引擎予以归档,因此CDC软件必须在此之前读取日志,或者能够读取已归档的日志。
- 创建可扫描的事务日志所需要的额外日志级别,可能会增加少量的性能开销。
- 当CDC应用程序发送数据时,目标数据库可能会意外地变得不可访问。它们必须缓冲未发送的数据,直到目标数据库重新联机上线。当然,如果未能完成该步骤,则可能导致数据的丢失或重复。
- 同样,如果源与目标之间的传输连接出现中断,系统也可能会发生故障,进而导致数据的丢失、记录的重复、以及需要从初始数据处重新启动加载。
基于触发器与事务日志的比较
总的说来,基于触发器的CDC和事务日志CDC,都是可用于构建反应式分布式系统的数据库设计模型。其中,基于触发器的CDC使用自己的事件日志,作为真实的数据来源,而事务日志CDC则依赖底层数据库的事务日志作为真实来源。
触发器可作为每个数据库事务的一部分,以捕获实时发生的事件。对于每次插入、更新或删除,都会由某个触发器去触发记录的变更。另一方面,事务日志CDC则可以独立于事务运行。它使用重做日志文件来记录的变更。由于CDC操作在发生时不会直接与数据库中的每个事务相关联,因此其性能会有所提升。
在实际应用中,各种常见的DBSync产品和DBConvert Studio都会使用基于触发器的数据库同步CDC方法。不过,对于集群数据库而言,基于触发器的方法可能会比使用MySQL的二进制日志、或PostgreSQL的事务日志,要相差许多。毕竟,MySQL在其官网上已声称:“在启用二进制日志的情况下,服务器的运行性能可能会被略微拖慢。但是,二进制日志在方便复制与恢复操作等方面的好处,通常超过性能上的微降。”(https://dev.mysql.com/doc/refman/8.0/en/binary-log.html)
小结
综上所述,CDC是现代数据架构的重要组成部分,可被用于将事务数据从源系统,传输到数据流中。我们需要它支持实时的事务数据,且不会对源系统造成重大的负载。它既不需要改变源应用程序,又要保证仅传输最少量的数据。因此,CDC更适合大体量的数据集。将来,我们会在那些强调数据分析和历史数据比较的企业级数据仓库中,看到CDC的广泛使用。
参考:
CDC是个啥,它是如何工作的?-51CTO.COM
相关文章:
变更数据捕获(CDC)
从广泛意义上说,全球许多企业每天都需要通过频繁的数据批量处理与加载,来定期将数据从一个数据库迁移到另一个数据库(或数据仓库)。这类定期批量加载的工作,往往既耗费时间,又会消耗原始系统的大量处理能力。因此,管理…...
【移动端表格组件】uniapp简单实现H5,小程序,APP多端兼容表格功能,复制即用,简单易懂【详细注释版本】
前言: 由于最近需要做移动端的项目 有个pc端的后台系统里面需要移一部分页面过来 而里面就有很多的表格,我就开始惯例网上先找前人栽的树,我好乘凉 然后找了一圈发现,不管是主流的移动端ui库或者网上自己写的帖子,或者…...
电子技术——CMOS 逻辑门电路
电子技术——CMOS 逻辑门电路 在本节我们介绍如何使用CMOS电路实现组合逻辑函数。在组合电路中,电路是瞬时发生的,也就是电路的输出之和当前的输入有关,并且电路是无记忆的也没有反馈。组合电路被大量的使用在当今的数字逻辑系统中。 晶体管…...
【C++】C++11 新特性
目录 1.列表初始化 1.1. C98中使用{}初始化的问题 1.2. 内置类型的列表初始化 1.3. 自定义类型的列表初始化 2. 变量类型推导 2.1. 为什么需要类型推导 2.2. decltype类型推导 2.2.1 为什么需要decltype 2.2.2. decltype 3. 对默认成员的控制(default、delete) 3.1. …...
JPA 相关注解说明
jpa相关注解 JPA(Java Persistence API)是一种Java规范,定义了一套标准的对象关系映射(ORM)API,用于将Java对象映射到关系型数据库中。JPA旨在统一各种ORM框架之间的差异,提供一种标准化的ORM解…...
SAP 生产订单/流程订单中日期的解释
SAP 生产订单/流程订单中日期的解释 基本开始日期:表示订单的开始日期 基本完成日期:表示订单的完成日期 我们在输入基本开始日期和基本完成日期时需要关注 调度 下面的“类型”,其中有向前、向后、当天日期等: 调度类型 为向前…...
Java设计模式笔记——七大设计原则
系列文章目录 第一章 Java 设计模式之七大设计原则 文章目录系列文章目录前言一、单一职责原则1.案例分析2.改进二、开闭原则1.案例分析2.改进三、里氏替换原则1.案例分析2.改进四、依赖倒转原则五、接口隔离原则1.案例分析2.改进六、合成复用原则1.案例分析2.改进七、迪米特原…...
记录第一次接口上线过程
新入职一家公司后,前三天一直在学习公司内部各种制度文化以及考试。 一直到第三天组长突然叫我过去,给了一个需求的思维导图,按照这个需求写这样一个接口, 其实还不错,不用自己去分析需求,按照这上面直接开…...
时序预测 | MATLAB实现Rmsprop算法优化LSTM长短期记忆神经网络时间序列多步预测(滚动预测未来,多指标,含验证Loss曲线)
时序预测 | MATLAB实现Rmsprop算法优化LSTM长短期记忆神经网络时间序列多步预测(滚动预测未来,多指标,含训练和验证Loss曲线) 目录 时序预测 | MATLAB实现Rmsprop算法优化LSTM长短期记忆神经网络时间序列多步预测(滚动预测未来,多指标,含训练和验证Loss曲线)效果一览基本描…...
如何利用Level2行情数据接口追板和交易股票?
十档行情看得更深的A股行情软件,我们在盘口数据中可以看到,买一到买五以及卖一到卖五,共10个价位的挂单情况,但基于上证所的level-2行情软件,视野则扩展到了买一到买十以及卖一到卖十数据,无疑比所有免费软…...
MySQL常用的聚合函数
聚合函数聚合函数对一组值进行运算,并返回单个值。也叫组合函数函数作用COUNT(*|列名) 统计查询结果的⾏数AVG(数值类型列名)求平均值,返回指定列数据的平均值SUM (数值类型列名)求和,返回指定列的总和MAX(列名)查询指定列的最⼤值MIN(列名)查…...
如何评估模糊测试工具-unibench的使用
unibench是一个用来评估模糊测试工具的benchmark。这个benchmark集成了20多个常用的测试程序,以及许多模糊测试工具。 这篇文章(https://zhuanlan.zhihu.com/p/421124258)对unibench进行了简单的介绍,本文就不再赘诉,…...
2023初级会计详细学习计划打卡表!自律逆袭,一次上岸!
2023年初级会计职称考试报名时间:2月7日-28日考试时间:5月13日—17日给大家整理了《经济法基础》和《初级会计实务》两科超实用的学习打卡表重要程度、难易度、易错点、要求掌握内容、章节估分等都全部总结在一起,一目了然!为什么…...
【Python】Python项目打包发布(四)(基于Nuitka打包PySide6项目)
Python项目打包发布汇总 【Python】Python项目打包发布(一)(基于Pyinstaller打包多目录项目) 【Python】Python项目打包发布(二)(基于Pyinstaller打包PyWebIO项目) 【Python】Pytho…...
一起Talk Android吧(第五百一十三回:Java中的byte数组与int变量相互转换)
文章目录整体思路示例代码各位看官们大家好,上一回中咱们说的例子是"自定义Dialog",这一回中咱们说的例子是" Java中的byte数组与int变量相互转换"。闲话休提,言归正转, 让我们一起Talk Android吧!在实际项目…...
22《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》中文分享
《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》 本人能力有限,如果错误欢迎批评指正。 第五章:Folding and Aggregation Are Cooperative Transitions (折叠和聚合是同时进行的) -蛋白质折叠的协同作…...
vue2 @hook 的解析与妙用
目录前言几种用法用法一 将放在多个生命周期的逻辑,统一到一个生命周期中用法二 监听子组件生命周期运行的情况运用场景场景一 许多时候,我们不得不在不同的生命周期中执行某些逻辑,并且这些逻辑会用到一些通用的变量,这些通用变量…...
网络技术|网络地址转换与IPv6|路由设计基础|4
对应讲义——p6 p7NAT例题例1解1例2解2例3解3例4解4一、IPv6地址用二进制格式表示128位的一个IPv6地址,按每16位为一个位段,划分为8个位段。若某个IPv6地址中出现多个连续的二进制0,可以通过压缩某个位段中的前导0来简化IPv6地址的表示。例如…...
MySQL运维知识
1 日志1.1 错误日志1.2 二进制日志查看二进制日志:mysqlbinlog ./binlog.000007purge master logs to binlog.000006reset mastershow variables like %binlog_expire_logs_seconds%默认二进制文件只存放30天,30天后会自动删除。1.3 查询日志1.4 慢查询日…...
易基因-MeRIP-seq揭示衰老和神经变性过程中m6A RNA甲基化修饰的保守下调机制
大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。2023年02月22日,《美国国家科学院院刊》(Proc Natl Acad Sci USA)期刊发表了题为“Conserved reduction of m6A RNA modifications during aging and neurodegeneration is lin…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
