Canal稳定监听MySQL binlog的前提是MySQL开启ROW格式binlog、授予SELECT/REPLICATION SLAVE/CLIENT权限、Canal实例配置正确;任一缺失将导致静默失败或无法收消息。

Canal 能稳定监听 MySQL binlog 增量变更,但前提是 MySQL 配置、Canal 实例参数、权限三者全部对齐;漏掉任一环节,canal-server 启动后会静默失败或持续报错,根本收不到第一条消息。
MySQL 必须开启 ROW 格式 binlog 并正确授权
Canal 依赖 MySQL 的 ROW 格式 binlog 才能解析出具体字段变更,MIXED 或 STATEMENT 会导致解析失败——现象是 Canal 日志里反复出现 parse failed 或直接无日志输出。
- 确认已开启:
SHOW VARIABLES LIKE 'log_bin';返回ON - 强制设为 ROW:
SET GLOBAL binlog_format = 'ROW';(必须写入my.cnf的[mysqld]段并重启 MySQL 才持久) - 创建专用用户:
CREATE USER 'canal'@'%' IDENTIFIED BY 'canal'; - 授予最小必要权限:
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; FLUSH PRIVILEGES; - MySQL 5.7+ 若报
Unknown system variable 'binlog_checksum',需检查canal.properties中canal.instance.dbUsername和密码是否匹配,且canal.instance.connectionCharset与 MySQL 服务端字符集一致(如UTF8MB4)
canal-server 的 instance 配置决定能否拉到数据
Canal 启动后不报错 ≠ 能消费数据。常见问题是 instance 配置未生效,或监听位点卡在初始位置不动。关键看 conf/example/instance.properties:
-
canal.instance.master.address必须填 MySQL 主库真实 IP + 端口(不能是 localhost,Docker 环境尤其注意网络互通) -
canal.instance.dbUsername/canal.instance.dbPassword必须与上一步创建的用户完全一致 -
canal.instance.filter.regex控制监听范围,例如只同步user_db\.user_info,避免用.*\..*全库扫描拖慢性能 - 首次启动时,
canal.instance.master.journal.name和canal.instance.master.position可留空,Canal 会自动定位到当前最新 binlog 位置;若手动指定,必须确保该 position 存在且未被 purge - 主从切换后,MySQL binlog 文件名重置(如
mysql-bin.000001→mysql-bin.000002),而 Canal 默认不会感知,需配合 ZooKeeper 或 Kafka 持久化位点,否则丢数据
消费延迟高或数据丢失,先查 buffer 和 batch 模式
延迟不是 Kafka 或 RocketMQ 的锅,大概率是 Canal 自身解析卡住。典型表现:MySQL 写入频繁,但下游几秒甚至几十秒才收到事件。
-
canal.instance.memory.buffer.size默认 16384(约 1.6 万条),表字段多、更新密集时极易满载阻塞;建议调大至1048576(100 万条) -
canal.instance.memory.batch.mode推荐设为MEMSIZE(按内存大小切批),而非默认的ITEMSIZE(按条数切批),避免单条大事务撑爆内存 - 关闭无用过滤逻辑:
canal.instance.filter.black.regex和正则太宽泛的filter.regex会触发全字段解析,显著拖慢速度 - Client 端别在
onEvent()回调里做耗时操作(如同步写 ES),应投递到本地队列或消息中间件后再异步处理
验证是否真正在监听:别只看日志,要看 binlog position 是否推进
Canal 日志里出现 subscribe filter regex: 和 start successful 只代表实例启动成功,不代表它正在消费。真正可靠的验证方式是:
- 在 MySQL 执行一条
INSERT,然后立刻查SHOW MASTER STATUS;记下File和Position - 等 2 秒,再执行一次
SHOW MASTER STATUS;,观察Position是否增长 - 同时查 Canal 日志中是否有类似
ack: binlog[mysql-bin.000005:123456789]的记录,且数字是否随 MySQL 的 Position 一起变 - 如果 Canal 的 ack position 长期不动,说明 eventParser 卡住——重点检查 MySQL 权限、网络连通性、binlog 格式、以及是否存在 DDL 语句(如
ALTER TABLE)导致解析异常
最容易被忽略的是:MySQL 主从切换后 Canal 无法自动识别新 binlog 文件起点,以及 Docker 容器内 Canal 无法解析宿主机 MySQL 的 hostname。这两处一旦出问题,数据就静默丢失,日志里却几乎不报错。


















