Canal能否正常运行,80%问题源于MySQL与Canal参数不匹配:MySQL必须启用ROW格式binlog、唯一非零server_id、log_bin=ON,并授权SELECT、REPLICATION SLAVE和REPLICATION CLIENT;Canal需正确配置master.position、slaveId、tsdb.enable及connectionCharset。

Canal 能不能跑起来,80% 的问题出在 MySQL 配置和 Canal 实例参数不匹配上,不是版本不兼容,而是 binlog-format、server_id、slaveId 这几个关键项没对齐,或者权限漏了 REPLICATION CLIENT。
MySQL 必须开 ROW 模式 + 正确 server_id
Canal 依赖 MySQL 的 binlog 日志流,而只有 ROW 格式才能拿到具体字段变更值(比如 UPDATE 后 name 从“张三”变“李四”)。STATEMENT 或 MIXED 会导致解析失败或数据丢失。
- 执行
SHOW VARIABLES LIKE 'binlog_format';,结果必须是ROW - 执行
SHOW VARIABLES LIKE 'server_id';,值不能为 0,且在整个集群中唯一(主库设为 1,从库不能也用 1) -
log_bin必须为ON;如果显示OFF,说明配置没生效或没重启 MySQL - 修改
/etc/my.cnf(或/etc/mysql/my.cnf)的[mysqld]段落,至少加这四行:log-bin=mysql-bin binlog-format=ROW server_id=1 expire_logs_days=3
- 改完后必须执行
sudo systemctl restart mysql(Ubuntu/Debian)或sudo systemctl restart mysqld(CentOS/RHEL)
同步账号权限不能只给 REPLICATION SLAVE
很多人照着文档只执行 GRANT REPLICATION SLAVE ON *.*,结果 Canal 启动时报 Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s)——其实缺的是 REPLICATION CLIENT,它用于查询 binlog 状态和位置。
- 创建账号时必须同时授权两个权限:
CREATE USER 'canal'@'%' IDENTIFIED BY 'StrongPassw0rd!'; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; FLUSH PRIVILEGES;
-
SELECT权限不是可选的:Canal 在启动时会查information_schema获取表结构,没它会卡在初始化阶段 - 生产环境建议把
'%'换成 Canal 所在服务器的 IP,例如'canal'@'192.168.10.22' - 不要用
GRANT ALL PRIVILEGES:Canal 不需要写权限,也不该有
canal.instance.master.position 初始值填错就收不到第一条日志
Canal 第一次启动时,要从某个 binlog 文件的某个偏移量开始拉取。这个偏移量填错,轻则跳过部分变更,重则直接报 Could not find first log file name in binary log index file。
- 首次部署建议留空
canal.instance.master.journal.name和canal.instance.master.position,让 Canal 自动定位到最新位置 - 如果必须指定起始点,先用
mysql -u root -p -e "SHOW MASTER STATUS;"查看当前File和Position,再填入instance.properties - 填错后 Canal 日志里会出现
parse failed或no available parser,但错误不明显,容易误判为网络或权限问题 - 注意
canal.instance.mysql.slaveId不能和 MySQL 实例的server_id冲突,也不能为 0(官方默认是 0,必须改)
Canal 启动后日志无报错但没数据输出
常见于过滤规则、字符集或实例名配置不当,现象是 canal.log 显示 start successful,但 instance.log 里没有 subscribe 或 ack 记录。
- 检查
canal.instance.filter.regex:默认是.*\..*(所有库所有表),若改成test\..*却没建test库,就会静默跳过 - 确认
canal.instance.connectionCharset和 MySQL 实际字符集一致,否则中文字段可能乱码或解析中断 - 启动命令是否带实例名:
./bin/startup.sh example;不带参数时默认只启example,但如果你改了目录名(如叫mysql_prod),就得显式指定 -
canal.instance.tsdb.enable=true必须开启,否则 position 无法持久化,重启后会重复消费或丢数据
最容易被忽略的是 slaveId 和 server_id 的冲突,以及 REPLICATION CLIENT 权限缺失——这两点不满足,Canal 连连接都建立不了,但日志里往往只报泛泛的 “connect failed”,不会明确指出缺哪个权限或 ID 冲突。


















