【Java】canal服务运行一段时间客户端遍历不到数据
# 【Java】canal 服务运行一段时间客户端遍历不到数据
canal:阿里巴巴的一款开源中间件,用于读取数据库 binlog 日志,实时发送给客户端。
问题:使用 canal 后运行一段时间,客户端一直轮询,但是 batchId 始终为 - 1,手动改动数据库数据后,仍然还是获取不到。
1.canal 服务读取出错了
检查 canal 日志关键是 logs\example 下的,看是否由报错提示,如报错列不匹配,或者类型转换异常等,可能是你修改了表结构导致,直接配置 tsdb 数据库,然后删除 meta.dat 缓存即可。可参考上一篇文章
2.canal 读取的 binlog 已被删除
这里首先要介绍 meta.data
位置位于 conf\example 下
{“clientDatas”:[{“clientIdentity”:{“clientId”:1001,“destination”:“example”,“filter”:".\…"},“cursor”:{“identity”:{“slaveId”:-1,“sourceAddress”:{“address”:“rm-m5epj85txc6175on5zo.mysql.rds.aliyuncs.com”,“port”:3306}},“postion”:{“gtid”:"",“included”:false,“journalName”:“mysql-bin.002943”,“position”:151295060,“serverId”:1430559368,“timestamp”:1627023747000}}}],“destination”:“example”}。
这个主要是用来记录 binlog 读取位置的。
首先我们找到 journalName,对应的是 master 数据库 binlog 日志文件名。
position 为读取到 binlog 的位置。
而数据库的 binlog 会随着运行越来越多,所以它会自动删除之前的 binlog 日志。
然后去数据库执行
1 | show master logs |
log_name 则为现有的 binlog 日志,查找 binlog 是否和 meta.dat 里面记录的一致,若 meta.data 记录的 binlog 不在里面,则表示已被删除。
可将 journalName 值改为现有的 binlog 日志,然后把 position 置为 4
为什么 canal 读取的 binlog 会被删除呢
1. 手动删除,服务器磁盘容易满,所以偶尔会有人手动删除 binlog 文件。
2.client 端报错,客户端读取到 canal 发过来的数据后进行处理,若处理出错,程序在逻辑上没有 ack 此 batchId,而是去反复执行,那么 client 端会一直执行此条 batchId 数据,此时后面数据会进入 client,而在后面的 batchid 数据进来后会报 canal 的错误,batchId ***,大致意思就是执行的前面的 batchId 发现后面的 batchid 了,然后 canal 就卡在这了,不在读取后面的 binlog,当后面的 binlog 被删除后,就和数据库的 binlog 对应不上了
首先要检查 client 端是否有报错,然后检查 canal 服务是否有报错,在检查 binlog 是否一致,若不一致再分析原因
# 关于我
Brath 是一个热爱技术的 Java 程序猿,公众号「InterviewCoder」定期分享有趣有料的精品原创文章!
非常感谢各位人才能看到这里,原创不易,文章如果有帮助可以关注、点赞、分享或评论,这都是对我的莫大支持!