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,触发器就成了唯一的选择。
适用场景:低并发、对实时性要求不高、数据库版本老旧或权限受限的环境。我个人建议,能不用就别用。
触发器方案的典型流程:
- 在源表上创建触发器(INSERT/UPDATE/DELETE各一个)。
- 触发器将变更记录写入
cdc_changelog表。 - CDC定时任务轮询
cdc_changelog表,获取增量数据。 - 处理完后标记或删除已消费的记录。
这里有个细节:触发器写入日志表和业务事务是同一个事务。如果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机制的数据流转路径。你可以直观地看到,日志解析是“旁路监听”,触发器是“业务内嵌”,时间戳是“定期轮询”。
3.6 选型建议
讲到这里,你应该心里有数了。我最后给几条实战建议:
- 新项目、高并发、实时性要求高——无脑选日志解析。Debezium + Kafka是黄金组合。
- 老旧系统、DBA不配合、并发低——触发器方案可以应急,但记得做好日志表的清理策略。
- 离线分析、T+1同步、不关心删除——时间戳方案够用,简单好维护。
个人习惯:我一般优先考虑日志解析。如果条件不允许,再退而求其次。触发器方案我基本只在面试题里见到,生产环境能不用就不用。