MySQL 开启 binlog 必须配置 log-bin、binlog-format=ROW 和 server-id;Debezium 连接需专用用户并授予 REPLICATION SLAVE 等权限;PostgreSQL CDC 要求 wal_level=logical 且配置复制槽。

MySQL 的 binlog 怎么开,不开就捕不到更新
不开启 binlog,CDC 就是空谈。默认 MySQL 是关闭的,得手动配。关键不是“能不能用”,而是“用什么格式”——必须设成 ROW 模式,STATEMENT 或 MIXED 会漏掉字段级变更,审计直接失效。
实操建议:
- 检查当前模式:
SHOW VARIABLES LIKE 'binlog_format';,不是ROW就得改 - 在
my.cnf里加三行:log-bin=mysql-bin、binlog-format=ROW、server-id=1(值不能为 0,且集群内唯一) - 重启 MySQL 后执行
SHOW MASTER STATUS;,有输出说明已生效 - 别跳过
server-id:没它,很多 CDC 工具(比如 Debezium)会拒绝连接
Debezium 连 MySQL 报 Access denied for user 怎么解
不是密码错,大概率是权限没给够。Debezium 需要的不止是 SELECT,它得读 binlog、查表结构、甚至建临时表。用普通应用账号连,90% 卡在这儿。
实操建议:
- 创建专用用户:
CREATE USER 'cdc_user'@'%' IDENTIFIED BY 'strong-pass'; - 授最小必要权限:
GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'cdc_user'@'%'; - 别漏
FLUSH PRIVILEGES;,否则权限不生效 - 如果 MySQL 8.0+,注意默认认证插件是
caching_sha2_password,Debezium 旧版不认,可加ALTER USER 'cdc_user'@'%' IDENTIFIED WITH mysql_native_password BY 'strong-pass';
更新记录里 timestamp 字段总是 null,是不是时间没同步
不是时间不同步,是 Debezium 默认不把数据库的 NOW() 或 CURRENT_TIMESTAMP 当作变更字段抓取。它只捕物理 binlog 中明确写入的值,而自动填充的时间戳往往不在 binlog 的 update rows 里。
实操建议:
- 在业务 SQL 更新时显式传时间:
UPDATE users SET name='x', updated_at=NOW() WHERE id=1; - 或用触发器补全:
BEFORE UPDATE触发器强制设updated_at = NOW() - 别依赖
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP——这个机制对 row-based binlog 是“隐形”的,CDC 工具看不到 - 如果非要用自动时间戳,得在 Debezium connector 配置里加
"database.history.skip.ddl.statements" : "true"并配合自定义 SMT(单消息转换),但复杂度陡增,一般不值得
PostgreSQL 用逻辑复制做 CDC,wal_level 设成 replica 还是 logical
必须是 logical。设成 replica 看似够用,但 Debezium / pgoutput 客户端会报 ERROR: logical decoding requires wal_level >= logical,连都连不上。
实操建议:
- 改
postgresql.conf:wal_level = logical,同时确认max_replication_slots >= 1(每个 CDC 表流占一个 slot) -
max_wal_senders至少设为 10,避免 slot 被挤掉或 WAL 被提前回收 - 重启后运行
SELECT * FROM pg_replication_slots;,能看到你的 slot 名称和 active 状态才算真正就位 - 别在生产库上反复删 slot:slot 不清理,WAL 就不释放,磁盘可能撑爆
字段级变更细节、事务边界、大事务拆分、DDL 同步——这些不是配置开一下就能稳住的,得盯着每条 event 的 before/after 结构和 source.ts_ms 时间戳对齐,不然审计链一断,就只能翻 binlog 手动捞了。










