不能只靠 binlog 自己搭,必须用 Canal、Flink CDC 等成熟组件;MySQL 必须配置唯一 server-id 和 binlog_format=ROW,且需专用账号授权 REPLICATION SLAVE/CLIENT 权限,否则同步链路无法启动或静默失败。

直接说结论:不能只靠 binlog 自己搭,必须用 Canal、Flink CDC 这类成熟消费者组件;否则你得自己解析日志格式、管理位点、处理事务边界、应对 DDL 变更——这些全是生产环境里会反复爆雷的点。
MySQL 必须先配对 server-id 和 binlog_format=ROW
这是所有同步链路的启动开关,缺一不可。很多团队卡在这一步,不是没开 binlog,而是开了但格式不对或 ID 冲突。
-
server-id必须是正整数,且在整个复制拓扑中唯一;Canal 或 Flink CDC 作为“假从库”,也得有自己独立的server-id,不能和真实从库撞车 -
binlog_format必须设为ROW,STATEMENT和MIXED在 UPDATE/DELETE 场景下无法保证行级精确性,下游消费时会丢变更或解析失败 - 配置必须写进
my.cnf的[mysqld]段,SET GLOBAL log_bin = ON是无效的,MySQL 5.7+ 直接报错 - 改完要重启 mysqld,然后执行
SHOW VARIABLES LIKE 'log_bin'和SHOW VARIABLES LIKE 'binlog_format'双重确认
Canal 启动前必须建专用账号并授权 REPLICATION SLAVE 和 REPLICATION CLIENT
Canal 不是连上去就能读 binlog 的,它需要两个底层权限才能拉取日志流和查询主库状态,少一个都会在连接时抛 ERROR 1227 或卡在 handshake 阶段。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 建账号命令示例:
CREATE USER 'canal'@'%' IDENTIFIED BY 'xxx'; - 授权命令必须包含:
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; - 注意不要漏掉
SELECT——Canal 初始化 instance 时会查information_schema获取表结构,没这个权限会静默失败,日志里只显示 “fetch schema failed” - 如果 MySQL 开了
lower_case_table_names=1,Canal 的表过滤规则(如canal.instance.filter.regex)必须全小写,否则匹配不到
Flink CDC 3.0 比 Canal 更省心,但 checkpoint 和 scan.startup.mode 必须配对
Flink CDC 原生支持全量+增量自动切换,不用手动导快照、记位点、切流,但它把复杂度转移到了 checkpoint 配置上。常见问题基本都出在这两个参数没对齐。
-
scan.startup.mode设为initial时,Flink 会先扫全量再接 binlog;设为latest-offset则跳过全量,直接从当前位点消费——选错会导致数据缺失或重复 -
checkpoint间隔必须小于 binlog 过期时间(expire_logs_days),否则任务重启后找不到历史日志,报错Could not find the binlog file - Doris sink 要开启
enable-delete才能正确处理 DELETE 事件;MySQL source 端若含大字段(如TEXT),需调大max_allowed_packet,否则解析中断 - DDL 变更(如新增列)默认不透传,需显式打开
scan.incremental.snapshot.enabled和schema.change.handling.mode,否则新字段值始终为 null
位点管理不是“记个文件名+position”就完事
真正上线后最常崩的不是连不上 MySQL,而是位点漂移、回退失败、跨文件断点续传丢失。binlog 文件轮转、GTID 开关、事务拆分都会让简单 position 失效。
- Canal 的
meta.dat文件存位点,但它只在正常 shutdown 时刷新;进程被 kill -9 或磁盘满会导致位点滞后,重启后重复消费 - Flink CDC 的 checkpoint 存的是 binlog filename + position + GTID set(如果启用了 GTID),比纯 position 更健壮,但要求 MySQL server_id 不能变,否则 GTID set 解析失败
- 大事务(比如单个 UPDATE 影响 50 万行)会被 binlog 拆成多个 event,但 Canal 默认按事务打包返回;如果消费端处理超时未 ack,整个事务会重推,造成下游重复
- 线上千万别用
PURGE BINARY LOGS清理日志,除非确认所有消费端已稳定追平;建议用expire_logs_days交由 MySQL 自动清理

















