本文字数:4437;估计阅读时间:12 分钟
作者:Kaushik Iska, Philip Dubé
简介
变更数据捕获(Change Data Capture,CDC)是现代数据架构中实现实时数据集成的重要技术模式。本文将深入探讨 ClickPipes —— ClickHouse Cloud 提供的原生数据集成方案 —— 如何在内部实现对 MySQL 数据库的 CDC。文章面向工程师与架构师,旨在帮助读者深入理解这一高可靠、高性能数据库复制机制背后的工作原理。
MySQL 复制基础
我们先回顾一下 MySQL 中的复制基本原理。
二进制日志:MySQL CDC 的核心
MySQL 的二进制日志(binlog)是其整个复制架构的基础。它会按顺序记录所有对数据库数据和结构所做的更改,概念图如下:
这些日志事件包括:
-
数据操作(INSERT、UPDATE、DELETE)
-
数据定义(CREATE、ALTER、DROP)
-
事务边界(BEGIN、COMMIT、ROLLBACK)
每个 binlog 事件都包含一个事件头(包含时间戳、服务器 ID 等元数据),以及一个事件体,记录实际的数据变更内容。
二进制日志格式
MySQL 支持三种 binlog 格式:
-
STATEMENT:记录执行的 SQL 语句
-
日志数据量小
-
遇到非确定性函数时可能导致复制不一致
-
不适用于 CDC 场景
-
-
ROW:记录实际变更的行数据
-
包含变更前和变更后的行镜像
-
数据最精确,但日志体积较大
-
是实现 CDC 所必须的格式
-
-
MIXED:默认采用 STATEMENT 格式,在需要时切换为 ROW 格式
-
同样不适用于 CDC
-
前提条件 — binlog_row_image = FULL
为了保证每次行级变更都能携带完整的变更前和变更后镜像,ClickPipes 要求源 MySQL 数据库将参数 binlog_row_image 设置为 'FULL'。这是 MySQL 8.x 中的默认配置。虽然 MINIMAL 或 NOBLOB 等轻量模式可以省略未发生变化的列,从而减少日志体积,但这会影响 ClickPipes 的幂等更新能力,并可能导致主键更新操作不安全。启用 FULL 模式主要会增加包含大量 UPDATE 的日志大小,而 INSERT 和 DELETE 基本不受影响,因此整体性能开销通常可控。
全局事务标识符(GTID)
GTID(Global Transaction Identifiers)提供了一种在多台服务器之间统一标识事务的方法:
GTID = source_id:transaction_id
示例 GTID 集:123e4567-e89b-12d3-a456-426614174000:1-1000,2000-3000
基于 GTID 的复制具有以下优势:
-
即使服务器重启,也能持续追踪事务
-
简化故障转移流程,实现高可用
-
支持灵活调整复制拓扑结构
ClickPipes MySQL CDC 架构
ClickPipes 使用一套稳定可靠的架构来支持对 MySQL 的变更数据捕获,既支持初始化加载,也支持持续复制。
架构概览
下图展示了 ClickPipes 中 MySQL CDC 的架构组成:
这条 CDC 数据通道主要包括以下几个核心组件:
-
连接管理模块:负责与源 MySQL 数据库建立并维护连接
-
Binlog 同步器:持续监听并同步 MySQL 的二进制日志流
-
事件处理器:将 binlog 中的事件解析为结构化的变更记录
-
表结构注册中心:跟踪和管理源端表的结构变更
-
检查点机制:记录处理进度,以便故障恢复时能够断点续传
-
类型转换层:将 MySQL 中的数据类型转换为 ClickHouse 兼容类型
-
写入模块:将变更数据高效写入 ClickHouse
连接与配置初始化
在启动 MySQL 的 CDC 流程时,ClickPipes 会执行一系列初始化操作,包括:
-
校验 MySQL 的相关配置是否符合要求
-
确保 binlog_format 被设置为 'ROW'
-
检查 binlog_row_image 是否为 'FULL'
-
验证二进制日志的保留时间设置
-
-
确认数据库是否启用了复制功能
-
检测是否支持 GTID 模式
-
确定起始的复制位置
-
-
提取源表的结构信息
-
获取每个字段的定义和数据类型
-
识别主键列
-
将 MySQL 的数据类型映射为 ClickHouse 的对应类型
-
初始数据加载
在开始实时变更同步之前,ClickPipes 会先进行一次初始快照操作:
-
创建一份数据的一致性快照
-
在 ClickHouse 中创建相应的目标表
-
记录当前的 binlog 位置或 GTID 作为后续变更流的起点
变更数据流
初始数据加载完成后,ClickPipes 会开始持续同步 MySQL 的数据变更:
-
建立与 MySQL binlog 流的连接
-
按照事务顺序处理变更事件
-
将行级事件解析为结构化的变更记录
-
将这些变更应用到 ClickHouse 中
-
持续更新检查点,以记录处理进度并支持容错恢复
基于 GTID 与 Binlog 位置的复制
ClickPipes 同时支持两种复制方式:
基于 GTID 的复制
GTID(全局事务标识符)为事务追踪提供了一种逻辑一致的方式。当一个事务提交后,GTID 集合会被更新并写入检查点,从而实现高效的断点续传,具备较强的容错能力,可适应服务器重启或拓扑结构调整等变化。
基于 Binlog 位置的复制
传统方式通过文件名和偏移位置标记复制进度。当 binlog 日志轮转时,系统会记录新的文件名及其位置。这种方式虽然有效,但在面对服务器变更和高可用场景时灵活性较差,一旦发生故障切换,通常需要重新初始化复制任务。
处理二进制日志事件
ClickPipes 能识别并处理多种类型的 binlog 事件:
行级变更事件
CDC 流水线会处理以下操作:
-
INSERT:提取列数据,生成插入记录
-
UPDATE:捕获修改前后的值,生成更新记录
-
DELETE:提取被删除的数据,生成删除记录
表结构变更事件
系统通过解析 DDL 语句检测并同步表结构的变化,具体包括:
-
利用 TiDB 的 SQL 解析器解析 DDL
-
提取结构变更(如新增列)
-
更新内部的结构注册表
-
将变更同步到 ClickHouse 的目标表中
类型映射与转换
ClickPipes 支持完整的 MySQL 数据类型,并对复杂情况做了额外处理,包括:
会话系统用如下方式来处理边界情况:
-
Enum 和 Set 类型值的映射(依赖 binlog_row_metadata)
-
二进制数据的解析和写入支持
性能优化机制
为了实现高效的 CDC 处理,ClickPipes 实施了以下优化措施:
事务级批处理
系统按事务对变更进行批量处理,以保持数据一致性,同时允许用户设置批处理的大小。
空闲检测
系统具备空闲检测能力,能在无数据流动的情况下及时释放资源,防止资源浪费。
并行处理机制
ClickPipes 在多个关键环节实现了并行处理,包括:
-
并行拉取表结构信息
-
批量处理表数据
-
并发写入 ClickHouse
智能重试策略
系统采用指数退避机制进行自动重试,可有效应对临时性失败,提升整体稳定性。
监控与可观测性
ClickPipes 提供了全面的 CDC 监控指标,便于用户掌握运行状态,包括:
-
每秒处理记录数
-
从 binlog 读取的数据量
-
复制延迟时间
-
错误率统计
-
当前复制位置或 GTID 信息
故障处理机制
ClickPipes 针对各种异常场景构建了完善的容错策略:
连接故障
系统内置重试机制,在网络故障时自动恢复连接,确保同步不中断。
结构不一致
系统能够检测源表与目标表之间的结构差异,并及时报告,避免因结构偏差导致数据写入错误。
故障恢复
借助检查点机制,系统在失败后能够自动恢复同步,确保数据不丢失、不重复。
开源社区贡献
在实现 ClickPipes 的 MySQL CDC 功能过程中,我们对关键依赖库进行了优化和扩展,特别是对 go-mysql-org/go-mysql 项目做出了如下贡献:
-
增加对 MariaDB 认证方式的支持
-
引入基于 log/slog 的现代日志系统
-
实现位运算层级优化,提升整体性能
-
添加对 SQL driver 的上下文管理能力
-
支持 MySQL 向量类型
这些开源贡献为 ClickPipes 提供了强健、可维护的复制基础。
最佳实践
为了让 ClickPipes 实现更优的 MySQL CDC 性能,建议遵循以下最佳实践:
-
MySQL 配置建议
-
将 binlog_format = 'ROW'
-
设置 binlog_row_image = 'FULL'
-
设置 binlog_row_metadata = 'FULL',以支持列级过滤、防止因源端忽略列导致的同步问题,并增强对 enum/set 类型的支持
-
设置合理的 binlog 保留时间,建议不少于 24 小时
-
-
表设计优化
-
所有表应配置主键
-
在变更频繁的表中避免使用大型对象字段(如 BLOB)
-
对于数据量大的表,建议进行合理分区
-
-
网络通信优化
-
优先将 ClickPipes 与 MySQL 部署在同一网络区域
-
使用 VPC 对等连接或专用网络链路提升传输效率
-
启用 TLS 加密保障数据传输的安全性
-
-
运行监控建议
-
实时跟踪复制延迟
-
监控 binlog 的增长速率
-
配置复制延迟的告警策略,及时响应异常情况
-
性能与基准测试
我们即将发布 ClickPipes MySQL CDC 的全面性能评估报告。根据目前的初步测试结果,该系统在处理多样化工作负载(包括高频小型事务、大规模批量写入,以及真实的混合型场景)中均表现出色。在理想环境下,每秒可处理数万条数据变更,整体同步延迟控制在 30 秒以内。
已知限制与边界情况
在使用 ClickPipes MySQL CDC 时,请注意以下限制:
-
结构变更支持:
-
完全支持新增列操作
-
对列的删除和重命名操作可识别,但不会自动应用到目标表
-
表名变更需要用户手动介入
-
-
数据类型限制:
-
二进制字段需要满足大小限制要求
-
-
复制配置要求:
-
必须启用并正确设置二进制日志功能
-
需要具有足够的数据库权限以读取 binlog
-
表需配置主键以确保同步性能
-
-
当前不支持 TRUNCATE 操作
结语
ClickPipes 提供了一套健壮且高效的 MySQL CDC 实现方案,能够稳定捕获并实时同步 MySQL 数据库中的变更内容。系统基于 MySQL 原生的复制能力,结合智能的数据处理流水线,实现了与 ClickHouse 的高效数据集成。
ClickPipes 的架构设计兼顾可靠性、性能和使用简便性,适用于运营型数据库同步、实时分析和数据湖建设等多种场景。深入理解其内部机制,能够帮助用户更好地优化数据流转路径,并快速定位与排查潜在问题。
如需了解 ClickPipes MySQL CDC 的更多使用细节,请参阅官方文档。目前该功能已进入私有预览阶段,欢迎申请体验。
征稿启示
面向社区长期正文,文章内容包括但不限于关于 ClickHouse 的技术研究、项目实践和创新做法等。建议行文风格干货输出&图文并茂。质量合格的文章将会发布在本公众号,优秀者也有机会推荐到 ClickHouse 官网。请将文章稿件的 WORD 版本发邮件至:Tracy.Wang@clickhouse.com