当前位置: 首页 > 科技观察

你用过MySOL的Binlog吗?来看看如何使用Binlog排查阿里开源项目Otter

时间:2023-03-17 17:31:56 科技观察

MySQL的binlog问题。相信大家都听说过,但可能不是日常使用。因此,本文结合一个小水獭坑的排查案例,分享一下binlog的日常使用。下面重点了解一下:binlog导出方式binlog分析方式结合案例分享开源项目otter的一个小坑1.案例背景周末突然接到报警,发现在线多的数据同步任务-clouddatabase挂了,logwrite显示Failedtoimportdata。错误的原因很明显:唯一索引冲突。我查看了源库的数据内容,确实更新了。但是目标库的数据内容确实有冲突,无法更新。2、排查过程本次数据同步任务使用阿里开源的数据库同步项目otter。你遇到过任何错误吗?otter项目是阿里巴巴开源的数据库同步系统。基于数据库增量日志分析,准实时同步到本地机房或远程机房的mysql/oracle数据库的分布式数据库同步系统。立即开始故障排除。2.1表结构是否一致?为什么源库没有冲突,而目标库有冲突?表结构不一致?还是源库的表结构变化没有同步到目标库?确认源库和目标库的表结构一致,并有对应的唯一索引udx_position。2.2查看源库的binlog源库是如何更新成功的?只能查看binlog。先导出线上正在使用的binlog文件。对数据库执行flushlogs命令会关闭当前正在写入的binlog文件,然后生成一个新的序列号加1的binlog文件供mysql服务器继续使用。等待几分钟,当前的binlog会被保存为日志文件,本例中为xxxx_binlog_mysqlbin.000005。然后下载到本地。通过mysqlbinlog命令分析,输出的是指定文件xxx.binlog,如下:mysqlbinlog--start-datetime='2020-11-2018:17:00'--stop-datetime='2020-11-2018:21:01'--base64-output=decode-rows-v-ddbxxxx_binlog_mysqlbin.000005>xxx.binlogbinlog格式binlog_format采用行模式。只保存记录的修改详情,不记录sql语句的上下文相关信息。优点:可以清楚的记录每一行数据的修改细节,不需要记录context相关的信息,所以procedure,function,andtriggercall触发了无法正确复制的问题。任何情况都可以复制,可以加快从数据库重放日志的效率,保证从库数据的一致性。通过--start-datatime和--stop-datetime行方式指定分析起止时间生成的sql编码需要解码,常规方法无法生成,需要添加相应的参数(--base64-output=decode-rows-v)可以显示sql语句binlog内容分析,sql过程如下(为了更好的看过程,这里没有显示binlog原文,而是一个逻辑过程):我们可以清楚的看到,源库通过一个事务中,交换position(唯一索引的列)的值,达到更新唯一索引的目的,不会造成冲突。那为什么目标库会冲突呢?2.3检查目标库的sql审计。由于数据同步失败,目标库的同步数据暂时不会写入对应的binlog记录。因此,我们需要通过sql审计来查看目标库的写状态。这里也展示了从sql审计中检索到的相关流程:Oh~My~God!交易中间的updateexchange过程居然合并了!!所以造成了唯一索引冲突,导致更新失败。3.为了验证,我又翻了一下otter的wiki,看到了关于《otter数据入库算法》的描述。https://github.com/alibaba/otter/wiki/Otter%E6%95%B0%E6%8D%AE%E5%85%A5%E5%BA%93%E7%AE%97%E6%B3%95运营整合案例确实存在。这样做有很多好处:insert/linerecordupdate执行mergesql,解决重复数据执行merge算法执行后,单个pk主键只有一条记录,降低了并行加载算法的复杂度(比如如batchmerge,parallel/serialprocessing,etc.)Synchronization相对于mysql的replication,摒弃了强一致性,性能提升了5倍左右。我找到了源代码并找到了DbLoadAction类。不幸的是,我们发现没有开关可以控制它。4.解决方案。至此,基本真相大白,问题的根源也找到了。因为otter在事务中合并了update操作,导致了目标库的唯一索引冲突。那么如何解决呢?在文档中看到这样一句话,对应这个case,或者其他唯一索引的变化,只能先删后插入,不能通过update来交换。