要在 MySQL 中配置 binlog(二进制日志),以便 Debezium 能够正确读取并捕获变更数据(CDC),需要完成以下关键配置步骤。Debezium 依赖 MySQL 的 row-based replication 模式,并要求开启 binlog。


✅ 1. 修改 MySQL 配置文件(my.cnf 或 my.ini)

通常位于:

  • Linux: /etc/mysql/my.cnf/etc/my.cnf

  • Windows: my.ini(在 MySQL 安装目录下)

[mysqld] 段落下添加或修改以下参数:

[mysqld]
# 启用二进制日志(必须指定一个名字)
log-bin=mysql-bin

# 设置服务器 ID(必须唯一,不能为0)
server-id=1

# 使用 ROW 格式的 binlog(Debezium 必须使用 ROW)
binlog-format=ROW

# (可选但推荐)记录完整行镜像,确保更新前后的完整数据
binlog_row_image=FULL

# (可选)设置 binlog 过期时间(单位:秒),例如保留30天
# MySQL 8.0.30 及之后版本使用binlog_expire_logs_seconds
binlog_expire_logs_seconds = 2592000

# (可选)如果监控的表没有主键,Debezium 可能无法可靠识别行,
# 建议所有表都有主键。

⚠️ 注意:

  • server-id 在复制环境中必须全局唯一,即使单机使用 Debezium 也必须设置且不为 0。

  • binlog-format=ROW 是 Debezium 的硬性要求。

  • binlog_row_image=FULL 确保 UPDATE 操作包含 before 和 after 的完整行数据,对 Debezium 解析至关重要。

三种 binlog 格式:

格式

全称

描述

适用场景

STATEMENT

基于语句的日志(Statement-Based Logging, SBL)

记录实际执行的 SQL 语句(如 UPDATE users SET name='Alice' WHERE id=1;)

简单、日志体积小,但存在非确定性函数等问题

ROW

基于行的日志(Row-Based Logging, RBL)

记录 每一行数据的实际变更(如“将 id=1 的行的 name 字段从 'Bob' 改为 'Alice'”)

Debezium / CDC 必须使用此格式,数据精确、安全

MIXED

混合模式(Mixed-Based Logging, MBL)

默认使用 STATEMENT,在不安全时自动切换为 ROW(如遇到 NOW(), RAND() 等非确定性函数)

兼顾性能与安全性,但行为不可控


🔍 各格式详细说明:

1. STATEMENT

  • 优点:

    • 日志体积小(只存 SQL)

    • 主从复制带宽占用低

  • 缺点:

    • 非确定性问题:如 INSERT INTO t SELECT NOW(); 在主从上执行时间不同,结果不一致。

    • 无法精确捕获“哪一行被改了”,对 CDC 工具(如 Debezium)不可用。

  • ❌ 不适用于 Debezium

2. ROW

  • 优点:

    • 精确记录每一行的变化(before/after)

    • 安全、可重现,无非确定性问题

    • 支持无主键表(但 Debezium 强烈建议有主键)

    • Debezium、Canal、Maxwell 等 CDC 工具的唯一选择

  • 缺点:

    • 日志体积大(尤其批量 UPDATE/DELETE)

    • 对大字段(如 BLOB、TEXT)可能产生大量日志

  • ✅ Debezium 强制要求此格式

💡 配合 binlog_row_image=FULL(默认),UPDATE 会记录修改前后的完整行;设为 MINIMAL 则只记录变化字段和主键(节省空间,但部分工具可能不支持)。

3. MIXED

  • MySQL 自动判断是否“安全”:

    • 安全语句 → 用 STATEMENT

    • 不安全语句(如含 UUID(), SYSDATE(), 自定义函数等)→ 自动转为 ROW

  • 看似兼顾,但对 CDC 工具有风险:

    • 如果某次变更被记为 STATEMENT,Debezium 无法解析,会导致连接器失败或跳过事件。

  • ❌ 不推荐用于 Debezium


✅ 2. 重启 MySQL 服务

修改配置后需重启 MySQL 使配置生效:

sudo systemctl restart mysql
# 或
sudo service mysql restart

✅ 3. 验证 binlog 是否启用

登录 MySQL 执行:

SHOW VARIABLES LIKE 'log_bin';          -- 应为 ON
SHOW VARIABLES LIKE 'binlog_format';     -- 应为 ROW
SHOW VARIABLES LIKE 'server_id';        -- 应为你设置的值(如 1)
SHOW MASTER STATUS;                     -- 应显示 binlog 文件和位置
SHOW BINARY LOGS;                       -- 查看所有 binlog 文件列表
SHOW SLAVE STATUS;                      -- 查看从库复制进度
mysqlbinlog 文件名                       -- 查看 binlog 内容

4.授予用户获取binlog的权限

如:debezium用户

CREATE USER 'debezium'@'%' IDENTIFIED BY 'your_password';
# 授权部分binlog权限,或者全部权限:all privileges
GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'debezium'@'%';
FLUSH PRIVILEGES;

🔒 权限说明:

  • SELECT:读取表结构

  • RELOAD:执行 FLUSH TABLES WITH READ LOCK(用于快照)

  • SHOW DATABASES:发现数据库

  • REPLICATION SLAVEREPLICATION CLIENT:读取 binlog

📌 补充建议

  • 所有被监控的表必须有主键,否则 Debezium 可能无法正确识别行变更。

  • 如果使用云数据库(如 AWS RDS、阿里云 RDS),需通过参数组启用 binlog 并设置格式为 ROW。

  • 监控 binlog 文件大小,避免磁盘爆满(可通过 expire_logs_daysbinlog_expire_logs_seconds 控制)。