插件窝 干货文章 分享docker canal踩坑历程(附解决方案)

分享docker canal踩坑历程(附解决方案)

Canal instance properties 配置 275    来源:    2025-05-02

Docker Canal 踩坑历程及解决方案

1. 网络配置问题

问题现象:Canal 容器无法连接到 MySQL 数据库

错误日志

com.alibaba.otter.canal.parse.exception.CanalParseException: connect failed: 127.0.0.1:3306

原因分析: - Docker 容器默认使用桥接网络,localhost 指向容器自身 - 如果 MySQL 运行在宿主机上,容器内使用 127.0.0.1 无法访问

解决方案: 1. 使用宿主机网络模式:

docker run --network=host canal/canal-server
  1. 或者使用 Docker 的特殊 DNS 名称:
# canal.properties 配置
canal.instance.mysql.slaveId=1234
canal.instance.master.address=host.docker.internal:3306

2. 权限问题

问题现象:Canal 无法获取 MySQL binlog

错误日志

ERROR c.a.o.canal.parse.inbound.mysql.dbsync.DirectLogFetcher - I/O error while reading from client socket
java.io.IOException: Received error packet: errno = 1236, sqlstate = HY000 errmsg = Could not find first log file name in binary log index file

原因分析: - Canal 需要 MySQL REPLICATION 权限 - binlog 格式需要设置为 ROW 模式

解决方案

-- MySQL 中执行
CREATE USER 'canal'@'%' IDENTIFIED BY 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;

-- 修改 MySQL 配置
[mysqld]
log-bin=mysql-bin
binlog-format=ROW
server_id=1

3. 时区问题

问题现象:时间类型数据解析错误

错误日志

WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> begin to find start position, it will be long time for reset or first position

原因分析: - Docker 容器默认使用 UTC 时区 - 与 MySQL 服务器时区不一致导致时间解析错误

解决方案: 1. 启动容器时指定时区:

docker run -e TZ=Asia/Shanghai canal/canal-server
  1. 或者在 canal.properties 中配置:
canal.instance.filter.transaction.entry = false
canal.instance.tsdb.enable = true
canal.instance.tsdb.spring.xml = classpath:spring/tsdb/h2-tsdb.xml

4. 内存不足问题

问题现象:Canal 容器频繁重启或被 OOM Kill

错误日志

Killed

原因分析: - Canal 默认 JVM 内存配置可能不足 - 处理大量 binlog 时内存消耗增加

解决方案: 1. 调整容器内存限制:

docker run -m 2g canal/canal-server
  1. 修改 JVM 参数:
docker run -e JAVA_OPTS="-Xms1g -Xmx2g -XX:+UseG1GC" canal/canal-server

5. 数据过滤问题

问题现象:订阅了不需要的表或库,导致资源浪费

解决方案: 在 instance.properties 中配置过滤规则:

# 白名单配置
canal.instance.filter.regex=.*\\..*
# 黑名单配置 
canal.instance.filter.black.regex=

# 精确配置示例
canal.instance.filter.regex=db1.user,db2.order.*

6. 高可用部署问题

问题现象:单点故障导致数据同步中断

解决方案: 1. 使用 Zookeeper 实现 HA:

# canal.properties
canal.zkServers=zookeeper1:2181,zookeeper2:2181,zookeeper3:2181
canal.instance.global.spring.xml = classpath:spring/default-instance.xml
  1. 部署多个 Canal 节点,使用相同的 zk 配置

7. 性能优化建议

  1. 批量处理
canal.instance.memory.batch.mode = MEMSIZE
canal.instance.memory.buffer.size = 16384
canal.instance.memory.buffer.memunit = 1024
  1. 启用 TSDB(时间序列数据库)存储位点信息:
canal.instance.tsdb.enable = true
canal.instance.tsdb.url = jdbc:h2:./conf/h2tsdb/Canal_1234
  1. 调整解析线程数
canal.instance.parser.parallel = true
canal.instance.parser.parallelThreadSize = 8

总结

Docker 环境下部署 Canal 常见问题主要集中在网络、权限、资源配置和配置细节上。通过合理的配置和优化,可以构建稳定高效的数据库变更捕获系统。建议在生产环境部署前充分测试,并根据实际业务量调整相关参数。