4、MySQL CDC Connector:MySQL CDC Source配置、全量+增量同步原理、Server ID配置策略、Binlog格式要求
好,咱们进入实战手册的第四个章节。前面聊了 CDC 的整体概念和 Flink CDC 的生态,今天咱们把目光聚焦到最常用的一个数据源——MySQL。
MySQL CDC Connector 可以说是整个 Flink CDC 生态里使用率最高的连接器,没有之一。我做过的大数据项目,十个里有八个第一站就是 MySQL。为什么?因为 MySQL 太普及了,业务库、用户库、订单库,到处都是它的影子。
这一章,我会把 MySQL CDC Source 的配置、全量+增量同步原理、Server ID 配置策略,还有 Binlog 格式要求,一次性给你讲透。嗯,咱们开始。
4.1 MySQL CDC Source 配置
先看配置。MySQL CDC Source 的配置其实不复杂,但有几个关键点,搞错了会踩坑。
4.1.1 基础配置项
一个典型的 MySQL CDC Source 配置长这样:
CREATE TABLE mysql_binlog_source (
id INT,
name STRING,
age INT,
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'mysql-cdc',
'hostname' = '192.168.1.100',
'port' = '3306',
'username' = 'cdc_user',
'password' = 'cdc_pass',
'database-name' = 'my_db',
'table-name' = 'my_table'
);
看着简单吧?但这里有几个隐藏的细节。
| 配置项 | 说明 | 我的建议 |
|---|---|---|
hostname |
MySQL 主机地址 | 别用 localhost,用真实 IP |
port |
MySQL 端口,默认 3306 | 确认防火墙放行 |
username |
连接用户 | 需要有 REPLICATION 权限 |
password |
用户密码 | 别硬编码,用变量或密钥管理 |
database-name |
要同步的数据库名 | 支持正则,如 my_.* |
table-name |
要同步的表名 | 也支持正则 |
'table-name' = 'order_.*'。这个功能在微服务拆分的场景下特别有用。
4.1.2 高级配置项
除了基础配置,还有几个高级参数,我建议你重点关注:
scan.startup.mode:启动模式。可选initial(全量+增量)、latest-offset(仅增量)、specific-offset(指定偏移量)。默认是initial。server-id:这个太重要了,后面单独讲。connect.timeout:连接超时,默认 30 秒。网络不好的环境可以调大。debezium.snapshot.mode:快照模式。默认initial,也可以改成when_needed。
scan.startup.mode 设置为 latest-offset,结果任务重启后,历史数据全丢了。因为 latest-offset 只从当前 Binlog 位置开始读,不会做全量快照。所以,如果你需要保证数据完整性,建议用 initial。
4.2 全量+增量同步原理
MySQL CDC 最牛的地方,就是能自动完成「全量同步 + 增量同步」的无缝衔接。说白了,就是先把历史数据全部读一遍,然后自动切换到 Binlog 监听模式,实时捕获变更。
这个流程,我画了一张图,你看一眼就明白了:
这个流程的核心思想是:先快照,后增量,无缝切换。Debezium 在底层帮我们做了大量工作,包括一致性快照、断点续传、Schema 变更处理等。
4.3 Server ID 配置策略
Server ID 这个问题,我见过太多人踩坑了。说白了,MySQL 的主从复制机制里,每个 Slave 都需要一个唯一的 Server ID。Flink CDC 本质上就是一个 Binlog 消费者,所以它也需要一个 Server ID。
4.3.1 为什么需要 Server ID?
MySQL 的 Binlog 是基于「主从复制」协议工作的。Master 会为每个 Slave 维护一个连接,每个 Slave 用 Server ID 来标识自己。如果两个 Slave 用了相同的 Server ID,Master 会认为它们是同一个客户端,导致其中一个连接被踢掉。
我记得有一次,线上环境同时跑了两个 Flink CDC 任务,都用了默认的 Server ID(5400),结果其中一个任务频繁断连,报错信息是 Slave with the same server_id is connected。排查了半天才发现是 Server ID 冲突。
4.3.2 配置建议
| 场景 | Server ID 配置 | 说明 |
|---|---|---|
| 单任务 | 固定值,如 5401 | 只要不和其他 Slave 冲突就行 |
| 多任务 | 每个任务不同值 | 建议用任务 ID + 随机数 |
| 动态扩缩容 | 自动生成 | 用 server-id 范围配置 |
5401-5409。这样即使任务内部有多个并行子任务,也能自动分配不同的 Server ID,避免冲突。
4.3.3 配置示例
-- 单任务固定配置
'server-id' = '5401'
-- 多任务范围配置
'server-id' = '5401-5409'
Slave with the same server_id is connected,导致 Binlog 消费断断续续。后来我改用范围配置 5401-5499,问题就解决了。
4.4 Binlog 格式要求
Binlog 格式,这个必须说清楚。MySQL 的 Binlog 有三种格式:STATEMENT、ROW、MIXED。Flink CDC 要求必须使用 ROW 格式。
4.4.1 为什么必须是 ROW 格式?
原因很简单:Flink CDC 需要知道每一行数据变更的「前后状态」。STATEMENT 格式只记录 SQL 语句,比如 UPDATE user SET name='张三' WHERE id=1,但不知道改之前是什么值。ROW 格式会记录每一行的完整变化,包括 before 和 after 镜像。
你想想看,如果不知道 before 状态,Flink CDC 怎么知道这条数据被改成了什么?怎么往下游发变更事件?
4.4.2 检查 Binlog 配置
登录 MySQL,执行以下命令检查:
-- 查看当前 Binlog 格式
SHOW VARIABLES LIKE 'binlog_format';
-- 查看 Binlog 是否开启
SHOW VARIABLES LIKE 'log_bin';
-- 查看 Binlog 行模式是否包含完整镜像
SHOW VARIABLES LIKE 'binlog_row_image';
如果 binlog_format 不是 ROW,需要修改 MySQL 配置文件:
[mysqld]
log_bin = mysql-bin
binlog_format = ROW
binlog_row_image = FULL
binlog_row_image 必须设置为 FULL。如果设置为 MINIMAL,Binlog 只记录被修改的列,不记录完整行信息。Flink CDC 需要完整的 before/after 镜像来构建变更事件,所以必须用 FULL。
4.4.3 权限要求
Flink CDC 连接 MySQL 的用户,需要以下权限:
- SELECT:读取全量数据
- REPLICATION SLAVE:连接 Binlog
- REPLICATION CLIENT:查看 Master 状态
- SHOW DATABASES:列举数据库
创建用户的 SQL 示例:
CREATE USER 'cdc_user'@'%' IDENTIFIED BY 'cdc_pass';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT, SHOW DATABASES ON *.* TO 'cdc_user'@'%';
FLUSH PRIVILEGES;
SELECT 和 REPLICATION 相关权限,不给 INSERT、UPDATE、DELETE,避免误操作。
4.5 本章小结
好,这一章的内容就这些。咱们回顾一下重点:
- MySQL CDC Source 配置:基础配置项要填对,高级配置项按需调整。
- 全量+增量同步原理:先快照后增量,Debezium 帮我们做了无缝衔接。
- Server ID 配置策略:每个任务必须用唯一的 Server ID,建议用范围配置。
- Binlog 格式要求:必须用 ROW 格式 + FULL 行镜像,权限要配齐。