3、CDC核心机制:日志解析、触发器、时间戳对比

聊到CDC的具体实现,市面上主流方案就三种:日志解析(Log-based CDC)、触发器(Trigger-based CDC)、时间戳(Timestamp-based CDC)。很多刚接触CDC的同事会问我:“到底选哪个?”我的回答通常是——没有银弹,得看场景。

这三种机制,说白了就是“怎么发现数据变了”。我分别拆开讲,最后再给你一张对比表,方便你选型时拍板。

3.1 日志解析(Log-based CDC)

这是目前生产环境里用得最多的方式。它的原理很简单:数据库的每一次写入、更新、删除,都会记录在事务日志里(比如MySQL的binlog、PostgreSQL的WAL、Oracle的Redo Log)。CDC工具直接去读这些日志,解析出变更事件,然后推给下游。

核心优势:对业务系统零侵入,不需要改表结构,不需要加触发器,性能损耗几乎可以忽略。

我在项目中遇到过一件事。有一次要给一个核心交易系统做实时数仓同步,那个库每秒写入量在5000 TPS以上。如果用触发器方案,DBA直接把我拉黑了。最后我们上了基于binlog的Debezium,线上跑了一年多,没出过问题。

不过,日志解析也有坑。我简单列几个:

  • 日志格式依赖数据库版本——MySQL 5.6和5.7的binlog格式有差异,升级数据库时CDC可能断流。
  • 日志保留策略——如果日志被清理了(比如binlog过期),CDC就得重新做全量快照。
  • DDL变更处理——表结构改了,下游消费端可能报错。

避坑指南:我曾经因为没注意binlog_format配置,导致CDC工具解析出来的数据全是错的。MySQL必须设置binlog_format=ROW,否则别想用Log-based CDC。

3.2 触发器(Trigger-based CDC)

触发器方案,就是在源表上创建INSERT、UPDATE、DELETE触发器。每次数据变更,触发器把变更记录写到一张专门的日志表里,CDC工具再去读这张日志表。

你想想看,这种方式有什么问题?

嗯,最直接的就是——性能开销。每次DML操作,数据库要多执行一次触发器逻辑,多写一条日志。在高并发场景下,这可能是压垮数据库的最后一根稻草。

但触发器方案也不是一无是处。我在一些老旧的Oracle系统里见过它的身影。那些系统没有开启归档日志,或者DBA不愿意开binlog,触发器就成了唯一的选择。

适用场景:低并发、对实时性要求不高、数据库版本老旧或权限受限的环境。我个人建议,能不用就别用。

触发器方案的典型流程:

  1. 在源表上创建触发器(INSERT/UPDATE/DELETE各一个)。
  2. 触发器将变更记录写入cdc_changelog表。
  3. CDC定时任务轮询cdc_changelog表,获取增量数据。
  4. 处理完后标记或删除已消费的记录。

这里有个细节:触发器写入日志表和业务事务是同一个事务。如果CDC消费失败,日志表数据不会丢失,但日志表会不断膨胀。我曾经见过一张日志表撑到几百GB,最后DBA半夜打电话让我去清数据……

3.3 时间戳(Timestamp-based CDC)

时间戳方案,是三种里最“朴素”的。它的做法是:在源表里加一个last_modified或update_time字段,每次更新数据时更新这个字段。CDC工具定期执行SELECT * FROM table WHERE update_time > last_poll_time,拿到增量数据。

听起来很简单对吧?但坑也不少。

  • 无法捕获删除操作——数据被删了,时间戳字段也没了,你查不到。
  • 时间精度问题——如果同一秒内有多条记录更新,可能会漏数据。
  • 对业务代码有侵入——你得保证每个更新操作都正确设置了时间戳字段。

我的建议:时间戳方案只适合做“准实时”同步,延迟可以接受分钟级,且不关心删除事件的场景。比如数据仓库的T+1增量抽取,或者离线分析。

我记得有一次,一个业务团队自己用时间戳方案做数据同步,结果因为应用代码里忘了更新update_time字段,导致下游数据一直对不上。排查了两天才找到原因。嗯,从那以后,我对时间戳方案就格外谨慎。

3.4 三种机制对比总表

下面这张表,我建议你收藏。选型的时候拿出来对照一下,基本不会跑偏。

对比维度 日志解析(Log-based) 触发器(Trigger-based) 时间戳(Timestamp-based)
对业务侵入性 无 中(需创建触发器) 高(需改表结构+业务代码)
性能影响 极低 较高(额外写日志) 低(仅查询)
实时性 秒级/毫秒级 秒级 分钟级(取决于轮询频率)
是否支持删除捕获 是 是 否
是否支持DDL捕获 部分支持 否 否
数据一致性 高(基于事务日志) 高(与业务事务同事务) 低(可能漏数据)
运维复杂度 中(需管理日志保留策略) 高(日志表膨胀、触发器维护) 低(简单轮询)
典型工具 Debezium、Canal、Maxwell 自定义脚本、部分ETL工具 DataX、Sqoop、自定义程序

3.5 三种机制的核心流程对比图

下面这张SVG图,我画了三种CDC机制的数据流转路径。你可以直观地看到,日志解析是“旁路监听”,触发器是“业务内嵌”,时间戳是“定期轮询”。

三种CDC核心机制对比流程图 三种CDC核心机制对比流程图 源数据库 事务日志(binlog/WAL) CDC解析器 下游消费者 ✅ 零侵入 ✅ 高性能 触发器(Trigger) 变更日志表 下游消费者 ⚠️ 性能开销大 ⚠️ 日志表膨胀 last_modified 时间戳字段 定时轮询任务 下游消费者 ❌ 无法捕获删除 ❌ 可能漏数据

3.6 选型建议

讲到这里,你应该心里有数了。我最后给几条实战建议:

  • 新项目、高并发、实时性要求高——无脑选日志解析。Debezium + Kafka是黄金组合。
  • 老旧系统、DBA不配合、并发低——触发器方案可以应急,但记得做好日志表的清理策略。
  • 离线分析、T+1同步、不关心删除——时间戳方案够用,简单好维护。

个人习惯:我一般优先考虑日志解析。如果条件不允许,再退而求其次。触发器方案我基本只在面试题里见到,生产环境能不用就不用。