文章首发于【博客园-陈树义】,点击跳转到原文Canal同步异常分析:Could not find first log file name in binary log index file。
公司搜索相关的业务系统采用了ElasticSearch + Canal实现了实时搜索(详情可参考文章:ElasticSearch + Canal 开发千万级的实时搜索系统)。
最近在查看线上Canal Server日志的时候发现了异常,这直接导致了其中一个数据库停止了数据同步。
从异常信息可以看到是实例为dbxxxx225_photo的实例发生了同步异常,对应的数据库机器为x.x.x.225,异常关键信息为:Could not find first log file name in binary log index file
。
仔细排查问题日志,还发现有另外一个异常:
这个异常大致意思是无法从该binlog位点(mysql-bin.000231)开始同步。于是我们登录对应的数据库主库,运行show master status\G
命令查看主从同步情况:
File: mysql-bin.000298
Position: 323871973
Binlog_Do_DB:
Binlog_Ignore_DB: mysql,test,information_schema,performance_schema,sys
Executed_Gtid_Set:
1 row in set (0.01 sec)
从上面的运行结果可以看到最新的文件是mysql-bin.000298
,而Canal Server还在同步位点mysql-bin.000231
。
我们知道MySQL保存的binlog文件是有限制的,当超过一定限制时,最早的文件会被删除。因此可以初步确定是因为数据库主从同步出现问题,导致Canal Server服务器所同步的binlog文件不存在,最终导致同步异常。
确定了问题所在,接下来就是如何解决问题了。因为binlog文件已经被删除了,所以在binlog位于231-298中间的数据是无法找回的,这导致了部分数据的丢失,但好在这部分数据并不是非常关键的数据,因此一部分的数据丢失可以承受。
因此我的解决方案是直接从最新的binlog位点进行同步。我们知道Canal Server和Canal Client之间的位点同步信息是存储在zookeeper节点中的,因此我们接下来要删除zookeeper上的节点信息,并重启相关服务。
关闭Canal Server、Canal Client
上面是系统简单的业务架构图。如果Canal Server、Canal Client没有关闭,是无法正常删除zookeeper上相应的节点的,所以我们要关闭所有的Canal Server和Canal Client。我一开始在删除的时候,只关闭了Canal Server,没有关闭Canal Client,后来在删除的时候发现无论如何都删除不了其中一个节点。最后将Canal Client也关闭之后,节点成功删除掉了。
所以,第一步就是要关闭所有的Canal Server和Canal Client节点,如果你部署了keepalive,另一台机器的也要关闭。
删除zookeeper节点信息
登录zookeeper所在服务器,使用zkCli.sh脚本进入到命令行。
使用ls命令查看canal正在运行的所有实例信息:
$ls /otter/canal/destinations
db10xxxx225003_photo db10xxxx225003_user ....
之后直接使用rmr节点删除该实例节点下的所有子节点:
rmr /otter/canal/destinations/db10xxxx225003_photo
修改Canal Server同步位点信息
进入Canal Server服务器的conf目录,修改对应实例的instance.properties文件,将其中的canal.instance.master.journal.name
和canal.instance.master.position
修改为主库中最新的值。其中journal.name表示最新的binlog文件名,master.position表示位点信息。我这里对应的就是下面:
File: mysql-bin.000298 //对应canal.instance.master.journal.name
Position: 323871973 //对应canal.instance.master.position
如果你部署了两台Canal Server组成keepalive,这里可以只修改其中一台Canal Server,因为当成功修改位点信息后,只要zookeeper中有位点信息,Canal Server就不会从本地配置文件读取。
修改完后,直接启动Canal Server,再启动Canal Client,这时候查看Kafka队列是否有增加对应的消息。一般情况下,都没有什么问题。
完成后,如果部署了keepalive,那么将其他的Canal Server和Canal Client都启动一下就可以了。
参考资料
- [1].CSDN.Could not find first log file name in binary log index file.[DB/OL].2017-10-09