引言
记录一次线上环境 Canal Adapter 无法自动同步 MySQL 数据到 Elasticsearch 的故障排查过程。尽管手动调用 ETL 接口能同步数据,但 Binlog 变更事件始终未触发自动同步。最终通过 重启 Canal Adapter 服务 解决问题,本文将深入分析根因、完整排查逻辑及涉及的关键技术点。
背景
我们有一个曲库搜索,是通过Elasticsearch进行查询的,每一本教材包含很多曲谱,教材以及曲谱的上下架操作通过后台管理系统进行操作, 变更状态后,需要同步Elasticsearch,这样保证前端用户能查询到最新教材或者曲谱,最近出现了教材可以同步但曲谱没办法自动同步的现象, 我本人是一名测开,以前未接触过这方面知识,因此把排查过程详细记录,加深记忆。
问题现象
-
环境:
- MySQL(阿里云 RDS) + Canal Server + Canal Adapter + Elasticsearch
- 同步表:
books(正常) 和sys_scores(失效)。
-
表现:
- 手动执行
/etl/es/ai_sys_scores.yml接口同步成功。 - 自动监听 Binlog 时,
sys_scores表数据变更未同步到 ES。 - 日志无报错,Canal Server 和 Adapter 显示“运行正常”。
- 手动执行
完整排查过程
基础检查
-
确认 Binlog 配置
-
验证 MySQL 的
binlog_format=ROW和binlog_row_image=FULL。 -
解析 Binlog 确认
sys_scores表变更已记录:
更改曲谱上下架状态,然后执行,如下命令:SHOW MASTER STATUS;此命令可以得到binlog文件名称,我这里使用的阿里云RDS,登录控制台下载该文件到本地,然后执行如下命令
mysqlbinlog --base64-output=decode-rows -v mysql-bin.000543 | grep "sys_scores"或者,也可以解析后,输出到文件,执行如下命令
mysqlbinlog -vv --base64-output=decode-rows mysql-bin.000543 > output.sql
结论 :Binlog 正常生成。 注意:针对阿里云 RDS for MySQL , 默认打开了 binlog , 并且账号默认具有 binlog dump 权限 , 不需要任何权限或者 binlog 设置
-
-
检查 Canal Adapter 配置
-
确认
ai_sys_scores.yml中:destination: ai_example # 与 Canal 实例名一致 _index: ai_scores_v2 # 索引存在 sql: "SELECT id, status FROM sys_scores"
结论 :配置无语法错误。
-
-
验证网络与权限
- Canal Server 能连接 MySQL,Adapter 能连接 ES。
- Canal 账号具备
REPLICATION SLAVE权限。
深入排查
-
查看 Canal Server 实例配置文件,是否将
sys_scores表过滤 打开目录下对应的 instance.properties 文件-
查找canal.instance.filter.regex配置:
canal.instance.filter.regex配置值为.*\..*结论:未过滤掉指定表
-
-
检查 Adapter 订阅状态
-
调用 Canal Server 运维接口:
echo "status" | nc 127.0.0.1 11112现象 :无响应 → Canal Server 运维端口未激活。
-
解决 :修改
canal.properties中canal.admin.port=11112并重启 Canal Server。
-
-
对比手动与自动同步差异
-
手动 ETL :直接执行 SQL 查询 MySQL 当前数据,写入 ES。
-
自动同步 :依赖 Binlog 事件,需满足:
- Canal Server 捕获事件 → Adapter 接收事件 → ES 写入。
-
关键解决步骤
进行了上面所有检查,并没有发现问题所在,然后准备开启 Adapter 的 DEBUG 日志,看从更详细日志中能否发现端倪
-
开启DEBUG日志 进入canal_adapter/conf目录,编辑application.yml文件,添加如下内容
logging: level: com.alibaba.otter.canal.client.adapter.es: DEBUG -
重启 Canal Adapter:
sh bin/stop.sh && sh bin/startup.sh结果 :自动同步立即恢复。
重启之后发现神奇的恢复了,后来想了想之前进行了哪些操作,编辑了ai_sys_scores.yml文件,然后我又编辑了该文件,未重启服务, 发现自动同步又失效了,立马重启之后,自动同步恢复正常了。添加日志操作解救了我啊,不然还想不到重启,一直尝试其他方法。
涉及的核心知识点
Canal 工作原理
-
canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送 dump 协议
-
MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
-
canal 解析 binary log 对象(原始为 byte 流)
-
Canal Server:
- 伪装为 MySQL Slave,订阅 Binlog 事件。
- 通过
instance.properties定义监听规则(库表过滤、位点存储)。
-
Canal Adapter:
- 作为 Canal Client,订阅 Server 的事件并转换为目标数据源(如 ES)的写入操作。
- 依赖
destination和groupId匹配 Server 的实例。
故障链分析
graph TD
A[自动同步失效] --> B{手动ETL成功?}
B -->|是| C[Binlog监听问题]
C --> D[Canal Server未捕获事件]
D --> E[过滤规则错误/权限不足]
C --> F[Adapter未处理事件]
F --> G[订阅关系失效/配置不匹配/修改配置未重启]
G --> H[重启Adapter恢复]
常见陷阱
-
配置大小写敏感:
destination和groupId必须与 Canal Server 完全一致。
-
热加载失效:
- 修改
*.yml后需重启 Adapter 或触发配置监控线程(部分版本需手动重启)。
- 修改
-
静默失败:
- ES 字段类型不匹配时,Adapter 可能丢弃数据且不报错。
4. 预防与优化建议
-
监控告警:
- 监听 Canal Server 和 Adapter 的日志关键词(
ERROR,WARN)。 - 定期校验 ES 索引数据与 MySQL 的一致性。
- 监听 Canal Server 和 Adapter 的日志关键词(
-
自动化运维:
- 使用 Canal Admin 管理实例和监控客户端状态。
- 配置 Adapter 定时重启(如每日低峰期)。
结语
看似简单的“重启大法”背后,实则是 订阅关系失效 和 运行时状态不一致 的深层问题。通过本次排查,不仅解决了问题,更梳理出 Canal 数据同步的核心链路和常见陷阱,希望对大家有帮助。
附录: