一.问题现象
由于我们的项目使用了canal进行数据同步,实时变更表数据变化。突然就出现了数据不能同步问题,查看客户端和服务端都是正常的。于是问题指向canal集群问题。
二.环境排查
1.我们的系统环境采用zooKeeper+canal 高可用集群部署方式,开始了逐一排查工作
zooKeeper部署在了三台不同的服务器上,所以依次查看是否正常工作
三台服务查看是否有zookeeper的线程服务,QuorumPeerMain如果有说明正常。
在查看canal服务CanalLauncher 都在说明服务正常运行。
2.查看canal example.log运行日志,发现问题所在
是因为后端开发人员在表里增加或者删除了字段导致的,和canal里面的本地存储信息不一致导致的。既然找到了问题,就开始解决问题:
(1)在canal.properties文件中添加配置信息
重启服务,然而发现并没有解决问题。
(2)找到canal本地存储信息,修改meta.dat的
timestamp时间戳改为最新的时间。
重启服务,然而发现并没有解决问题。
(3)直接暴力删除h2.mv.db文件,这里存储着同步的表结构信息。在删除后,canal在重启后,会自动创建最新的信息和mysql的表结构信息达到一致。重启服务,不在报错,可以正常工作了。
(4)还有个最好的方式,就是不要让canal的同步信息存储在本地h2数据文件里。存储到mysql数据库中。
在canal.properties里面配置tsdb的mysql数据库,数据库连接换成你自己的。具体配置如下:
canal.instance.tsdb.enable = true
canal.instance.tsdb.dir =
c
a
n
a
l
.
f
i
l
e
.
d
a
t
a
.
d
i
r
:
.
.
/
c
o
n
f
/
{canal.file.data.dir:../conf}/
canal.file.data.dir:../conf/{canal.instance.destination:}
#canal.instance.tsdb.url = jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
canal.instance.tsdb.url=jdbc:mysql://XXXXX:3306/canal_tsdb
canal.instance.tsdb.dbUsername = root
canal.instance.tsdb.dbPassword = root
#canal.instance.tsdb.spring.xml = classpath:spring/tsdb/h2-tsdb.xml
canal.instance.tsdb.spring.xml = classpath:spring/tsdb/mysql-tsdb.xml
在数据库里面创建canal_tsdb数据库,数据库的用户需要有创建表的权限。
create database canal_tsdb;
(5)最后终极方案就是等待最新版的canal增加时序表结构的能力