tidb-dm同步数据丢失问题

【 TiDB 使用环境】生产环境
【 TiDB 版本】6.5.3
【复现路径】上游导入数据大概300万,导入之后一条sql更新数据
【遇到的问题:问题现象及影响】
一条sql执行的更新中有部分数据未同步到下游,dm同步没有报错

多给一些细节。你这么问我只能给你算一卦。

4 个赞

1.上下游是异构表结构,表结构和表名不完全一致.
2.source的配置文件没有啥特别的就是指定源和账号密码
enable-gtid: false
relay-dir: relay-dir
flavor: mysql
charset: “”
enable-relay: false
relay-binlog-name: “”
relay-binlog-gtid: “”
source-id: test
from:
host: 10.xx
port: 3306
user: xx
password: xxx
max-allowed-packet: null
session: {}
security: null
3.task配置文件的一些内容

task-mode: incremental
is-sharding: true
shard-mode: pessimistic
ignore-checking-items: []
meta-schema: dm_meta
enable-heartbeat: false
heartbeat-update-interval: 0
heartbeat-report-interval: 0
timezone: ""
case-sensitive: true
--------------
routes:
  route-01:
    schema-pattern: ~^db_test
    table-pattern: ~^test20.*
    target-schema: new_db
    target-table: test_new

4.上游myisam表
5.先执行load data infile into 上游表
6.然后执行update testxx set price=xx,后发现部分设置的price有同步到下游,部分没有

1 个赞

感觉是不是myisam表的问题

和myisam表没有关系,和binlog有关系。
你执行update testxx set price=xx后,在binlog row模式下,每一行变更都是一条binlog消息。
这个同步过程可能是要花点时间的。

tiup dmctl query-status [task-name]

查询一下这个任务,看看这个任务的状态。

结果中unit字段是Sync. syncerBinlog的位置追上master了才是同步完成了。

query-status已经是是到了最新的binlog文件和binlog位置,所以同步没有延迟

应该跟myisam不支持事务有一定的关系的

感觉还是和myisam有关系,改成innodb类型

我也是这么觉得的

用mysqlbinlog把binlog解析出来。

参考这个。

然后去看对应没有更新的行,有没有对应的binlog。如果有,找到位置,把原来全量任务关了,开个增量任务,重新设置一下binlog位置,看同步后是否能更新。

不能更新再看日志吧。没什么其他的好办法,就是一点一点查。

把myisam改成innodb表试试?

想过,但是这种日表按天以myisam表格式上传,改成innodb,需要在上传的时候改回去,执行时间太久了

一次产生太多的binlog,因为没有支持事务,到了下游如果系统繁忙可能存在写入丢失,就会出现部分更新成功部分更新不成功,而且binlog同步的位置是没问题的。

写入丢失的原因是什么呢?

正常情况下,dm同步到的binlog位置是不会记错的。下游挂了也不影响,等下游起来,resume task就可以了。

你这个场景下同步少了一部分,我能想到的做法是因为你的update没有带where导致binlog在row模式下,一下写了巨量的binlog。这个时候上游在处理这个问题的时候,没有确认dm同步是否完成,就把上游的binlog文件删掉了。

这种情况下才会缺。

怀疑是下游写入繁忙的时候丢了binlog

1 个赞

下游丢的话,大概率还是过滤条件设置的有问题。

验证方法就是把binlog的位置调回去,重新同步一下,如果还是没更新就是这个问题了。

如果你怀疑是dm的bug导致的丢弃的话,还需要一个复现的方法。我用dm有一段时间了,下游即使集群升级也没出现过数据丢的情况。