【 TiDB 使用环境】生产环境
【 TiDB 版本】6.5.3
【复现路径】上游导入数据大概300万,导入之后一条sql更新数据
【遇到的问题:问题现象及影响】
一条sql执行的更新中有部分数据未同步到下游,dm同步没有报错
多给一些细节。你这么问我只能给你算一卦。
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有同步到下游,部分没有
和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
下游丢的话,大概率还是过滤条件设置的有问题。
验证方法就是把binlog的位置调回去,重新同步一下,如果还是没更新就是这个问题了。
如果你怀疑是dm的bug导致的丢弃的话,还需要一个复现的方法。我用dm有一段时间了,下游即使集群升级也没出现过数据丢的情况。