大数据-263 实时数仓-Canal 增量订阅与消费原理:MySQL Binlog 数据同步实践

张开发
2026/4/10 23:20:47 15 分钟阅读

分享文章

大数据-263 实时数仓-Canal 增量订阅与消费原理:MySQL Binlog 数据同步实践
TL;DR场景需要实时同步 MySQL 数据变更到下游系统Kafka、ES、HDFS 等结论Canal 通过模拟 MySQL 从库协议解析 binlog 实现增量数据捕获产出完整的 Canal 工作原理与 MySQL binlog 配置指南版本矩阵功能状态说明Binlog 解析✅ 已验证支持 ROW/STATEMENT/MIXED 格式解析从库协议模拟✅ 已验证COM_REGISTER_SLAVE COM_BINLOG_DUMPEvent/Entry 模型✅ 已验证标准化的数据变更事件封装增量订阅消费✅ 已验证支持 Kafka/RocketMQ/HDFS/ES 等下游断点续传⚠️ 待验证依赖位点记录需实际环境测试工作原理Canal 是一款用于 MySQL 数据库 binlog 增量订阅和消费的开源工具。它主要用于解决数据同步和分布式事务问题支持将数据库变更同步到其他系统中比如消息队列、大数据平台等。复制过程分为三步Master 主库将改变记录写进二进制 binary log 中Slave 从库向 MySQL Master 发送 DUMP 协议将 Master 主库的 binary log events 拷贝到它的中继日志relay log。Slave 从库读取并重做中继日志中的事件将改变的数据同步到自己的数据库核心概念Binlog (Binary Log)MySQL 的二进制日志记录数据库中数据变更的所有事件如 INSERT、UPDATE、DELETE 等操作。Canal 通过解析 binlog 来捕获这些数据变更。主从复制机制MySQL 支持主从复制主库将 binlog 传输到从库从库根据 binlog 重放操作实现数据同步。Canal 模拟 MySQL 从库的行为通过伪装从库来接收 binlog 数据。Dump 和 ParseDump 阶段通过模拟 MySQL Slave 的协议获取 binlog 数据流。Parse 阶段对 binlog 数据进行解析转换为可消费的数据结构。Event 与 Entry 模型Canal 会将 binlog 数据转换为事件流Event包含具体的 SQL 操作及影响的表和数据内容。工作流程伪装 Slave连接 MasterCanal 模拟 MySQL 从库执行 COM_REGISTER_SLAVE 命令向主库注册并请求从某个位置开始拉取 binlog。连接过程类似于 MySQL 主从复制协议。拉取 Binlog 数据Canal 发送 BINLOG_DUMP 命令从主库获取 binlog 日志流。解析 Binlog 数据Canal 接收到二进制日志后会按照 MySQL binlog 格式进行解析将其还原为 SQL 操作或数据变更事件。格式化 Event 数据Canal 会将解析出的 binlog 数据转换为内部的 Event 对象。Event 包含表名、主键、操作类型插入、更新、删除以及具体的数据内容。数据投递与消费Canal 将解析后的 Event 提供给消费端如 Kafka、RocketMQ 等消息队列或直接写入 HDFS、Elasticsearch 等存储系统。消费端可以根据需要进行实时处理或分析。数据流详细过程模拟 Slave 同步 binlogCanal 模拟 Slave 发送 COM_BINLOG_DUMP 请求到主库。主库接收到请求后开始将 binlog 数据发送给 Canal。Canal 记录 binlog 的位点position信息便于断点续传。Binlog 数据解析Canal 按照 MySQL 的 binlog 格式解析出各类事件Query EventSQL 语句事件如 DDL 操作CREATE TABLE 等。Row Event行级操作事件具体包括Write Rows (INSERT)Update Rows (UPDATE)Delete Rows (DELETE)Canal 将这些事件转换为通用的 Entry 格式并封装具体的行数据和元数据信息。投递与消费处理Canal 提供的事件数据会被推送到消息队列Kafka、RabbitMQ或存储系统HDFS、ElasticSearch。下游应用从这些队列或存储中获取数据进行实时分析、同步、索引等操作。Binlog 消息结构Canal 将 binlog 转换为统一的消息格式主要包括以下几部分Header描述消息的元信息例如数据库名称、表名称、操作类型等。Row Data记录表的行变更信息包括主键和列数据旧值、新值。Transaction Info支持事务的开始和结束标志保证数据一致性。MySQL Binlogbinlog 介绍MySQL 的二进制日志可以说是 MySQL 最重要的日志了它记录了所有的 DDL 和 DML除了数据查询语句语句以事件形式记录还包含语句执行的消耗时间MySQL 的二进制日志是事物安全型的。一般来说开启二进制日志会损耗 1% 的性能二进制有两个最重要的场景MySQL Replication在 Master 端开启 BinlogMaster 把它的二进制日志传递给 Slaves 来到达 Master-Slave 数据一致的目的。数据恢复通过使用 MySQLBinlog 工具来使恢复数据。二进制文件包括两类文件二进制日志索引文件文件后缀为.index用于记录所有的二进制文件二进制日志文件文件名后缀.0000*记录数据库所有的 DDL 和 DML除了查询语句语句事件。binlog 开启我们先打开配置文件vim/etc/my.cnf.d/mariadb-server.cnf在 MySQL 的配置文件在[mysqld]的区块下添加log-binmysql-bin这个表示 binlog 日志的前缀是 mysql-bin以后生成的日志文件是 mysql-bin.123456 的文件后面的数字按顺序生成。每次 MySQL 重启或者达到单个文件大小的阈值时新生一个文件按顺序编号。退出保存后重启 MySQL 服务systemctl restart mariadbbinlog 分类设置MySQL binlog 的格式有三种分别是STATEMENT、ROW、MIXED。statement语句级binlog 会记录每次执行写操作的语句。相对 row 模式节省空间但是可能产生不一致性比如update tt set create_datenow()此时如果用 binlog 恢复由于执行时间点不同所以结果也不同。优点节省空间缺点有可能造成数据不一致row行级binlog 会记录每次操作后每行记录的变化。优点保持数据的绝对一致性因为不管 SQL 是什么引用了什么函数它只记录执行后的效果缺点占用较大空间mixedstatement 的升级版本一定程度上解决了因为一些情况而造成的 statement 模式不一致的问题。比如某些情况当函数中包含 UUID 时包含 AUTO_INCREMENT 字段的表被更新时执行 INSERT DELAYED 语句时用 UDF 时按照 ROW 的方式进行处理。优点节省空间同时兼顾了一定的一致性缺点还有极个别情况依旧会造成不一致另外 statement 和 mixed 对于需要 binlog 的监控的情况都不方便。错误速查卡症状根因定位修复Canal 连接主库失败MySQL 未开启 binlog 或用户权限不足检查show master status和show grants for canal确保主库开启 binlog并为 canal 用户授予 REPLICATION SLAVE 权限binlog 位点不存在请求的 position 已被清理查看show master logs确认可用范围调整主库expire_logs_days或从最新位点开始消费解析异常 Eventbinlog 格式为混合模式且包含不可解析函数检查 binlog 格式show variables like binlog_format建议生产环境使用 ROW 模式数据不一致statement 模式下使用 now()/uuid() 等非确定性函数对比 binlog 重放结果与源数据切换为 ROW 模式延迟过高网络带宽不足或下游消费能力弱监控 Canal metrics 和下游队列堆积增加消费者实例或优化下游处理能力

更多文章