Flink SQL 里的 MySQL 源表
mysql-cdc 连接器把一张 MySQL 表声明成 Flink 里的动态表:作业启动后先按主键切块做全量快照,快照完成后无缝切换到位点读取 binlog 增量,因此同一段 SQL 既能做初始化加载又能持续消费变更。它替代了早期「DataX 拉全量 + Canal 收增量」的两段式拼装,多用于实时数仓的 ODS 层落地。源表只负责读取,写入目标表由 jdbc、kafka、hudi 等下游连接器承担。
基本信息
| 适用平台 | Flink 1.13+ 配合 flink-connector-mysql-cdc 2.x |
|---|---|
| 源库要求 | MySQL 5.7 / 8.0,binlog_format=ROW |
| 必需参数 | hostname、port、username、password、database-name、table-name |
| 主键约定 | 主键列必须写成 PRIMARY KEY (col) NOT ENFORCED |
| 账号权限 | SELECT、RELOAD、SHOW DATABASES、REPLICATION SLAVE、REPLICATION CLIENT |
| 快照方式 | 2.0 起默认无锁增量快照,全量阶段不加全局锁 |
典型使用场景
- 实时数仓 ODS 层:把业务库订单、用户表近乎实时地同步进湖仓
- 维表关联:订单流 join 一张低频变更的 MySQL 维表做实时打宽
- 全量与增量一次搞定:新表接入时不用再单独跑一遍初始化脚本
- 轻量 CDC:业务量不大、不想为同步单独维护 Canal / Debezium 集群时
- 对账与看板:把变更事件投递到 Kafka,供下游多消费方各自取用
完整示例
完整示例
CREATE TABLE orders (
order_id BIGINT,
user_id BIGINT,
amount DECIMAL(12,2),
status STRING,
created_at TIMESTAMP(3),
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'connector' = 'mysql-cdc',
'hostname' = '10.0.0.5',
'port' = '3306',
'username' = 'cdc_ro',
'password' = '***',
'database-name' = 'app',
'table-name' = 'orders',
'server-time-zone' = 'Asia/Shanghai',
'scan.startup.mode' = 'initial',
'scan.incremental.snapshot.chunk.size' = '8096' -- 每块行数,调小降低源库压力
);
-- 接入后就是一张普通流表,可直接聚合
SELECT status, COUNT(*) FROM orders GROUP BY status;关键参数读法
| 参数 | 作用 | 注意 |
|---|---|---|
| scan.startup.mode | initial 先全量再增量;latest-offset 只读增量 | 漏改时新建作业会重新拉一次全量 |
| server-time-zone | 声明源库会话时区 | 不设常导致 TIMESTAMP 整体偏移 8 小时 |
| scan.incremental.snapshot.chunk.size | 快照分块大小(行数) | 过大会在高峰期拉高源库读压力 |
| scan.snapshot.fetch.size | 快照读取的单批行数 | 与上项配合控制读取节奏 |
| debezium.* 前缀参数 | 透传给底层 Debezium 的选项 | 仅在有明确需求时设置,避免改坏默认行为 |
不设 server-time-zone 时 TIMESTAMP 列常见整体偏移 8 小时,联调先把时间列对一遍。
连接器需要读取 binlog,账号权限不足时报错往往发生在启动阶段而非语法解析阶段;同时 MySQL 的 binlog 保留时长要覆盖最长可能的作业停机时间,否则重启会因位点过期而失败。