canal账号必须同时具备select、replication slave和replication client权限:replication slave用于拉取binlog,replication client用于执行show master status等定位位点操作,select用于初始化时读取information_schema获取表结构,缺一不可。

Canal账号必须同时具备REPLICATION SLAVE和SELECT权限
Canal不是普通客户端,它会伪装成MySQL从库去拉取binlog,所以REPLICATION SLAVE权限不可省;但它在启动初始化阶段还要读information_schema查表结构,没SELECT权限会卡死在“waiting for table metadata”状态。很多人只给了复制权限,结果Canal日志里反复报java.sql.SQLException: Access denied,却查不到具体哪条SQL被拒——其实是第一次建连接时就失败了。
正确做法是用两条独立语句授权:
-
CREATE USER 'canal'@'192.168.10.22' IDENTIFIED BY 'StrongPassw0rd!';(生产环境严禁用'%') GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'192.168.10.22';FLUSH PRIVILEGES;
binlog_row_image必须设为FULL
Canal解析ROW格式binlog时,依赖每条变更事件中包含完整的行前镜像(before image)和后镜像(after image)。如果binlog_row_image是MINIMAL或NOBLOB,UPDATE/DELETE事件里可能缺失旧值字段,导致Canal无法生成准确的diff或无法做幂等判断。
检查和设置方式:
- 查当前值:
SHOW VARIABLES LIKE 'binlog_row_image';(必须返回FULL) - 临时生效:
SET GLOBAL binlog_row_image = 'FULL'; - 永久生效:在
my.cnf的[mysqld]段加binlog_row_image = FULL,然后重启MySQL
账号host必须匹配Canal服务器真实IP
MySQL用户是user@host联合主键,'canal'@'%'看似方便,但在生产环境会触发两个风险:一是违反最小权限原则,二是某些云厂商RDS默认禁用通配符host远程登录。更关键的是,如果Canal Server部署在NAT网关后,MySQL看到的源IP可能是网关地址,而非容器内网IP,此时'canal'@'172.18.0.5'这种Docker内部IP反而连不上。
实操建议:
- 先在Canal服务器上执行
mysql -h -u root -p -e "SELECT USER();",确认实际连接时MySQL记录的host值 - 用该host值创建账号,例如
'canal'@'192.168.10.22'或'canal'@'10.0.1.100' - 若MySQL 8.0+,注意
CREATE USER和GRANT必须分两步,不能合并在一条语句里
别漏掉REPLICATION CLIENT权限
这个权限常被忽略,但它决定了Canal能否执行SHOW MASTER STATUS和SHOW BINLOG EVENTS。Canal启动时会主动调用这些命令来定位起始位点,尤其在断点续传或指定destination配置时。缺少它会导致日志里出现access denied for operation SHOW MASTER STATUS,但错误提示不明显,容易误判为网络或账号密码问题。
验证方法:
- 用Canal账号登录MySQL:
mysql -h -u canal -p - 手动执行:
SHOW MASTER STATUS;和SHOW BINARY LOGS;,都应能正常返回 - 若报错
ERROR 1227 (42501): Access denied,说明REPLICATION CLIENT缺失
最易被忽略的其实是权限生效顺序:改完my.cnf后只重启MySQL,但没跑FLUSH PRIVILEGES,或者改了权限却忘了重启Canal进程让它重新建连接——这时候看日志全是“connected”,其实用的还是旧连接池里的失效凭证。











