使用dm工具,同步汇集mysql库中每天建新表的情况出错

【 TiDB 使用环境】测试
【 TiDB 版本】
Release Version: v6.5.1
Edition: Community
Git Commit Hash: 4084b077d615f9dc0a41cf2e30bc6e1a02332df2
Git Branch: heads/refs/tags/v6.5.1
UTC Build Time: 2023-03-07 16:12:08
GoVersion: go1.19.5
Race Enabled: false
TiKV Min Version: 6.2.0-alpha
Check Table Before Drop: false
Store: tikv
【 DM 版本】
v6.6.0
【复现路径】
上游日志表是每天添加一个新表,如今天就新建一个log_20230427的表放数据,明天就变成log_20230428的表来放数据。
因为想把多个上游数据归集到一个tidb表中,
所以dm路由配置如下:
route-Log:
schema-pattern: “China_Log”
table-pattern: “Log_"
target-schema: downStream
target-table: “Log_date”
extract-table:
table-regexp: "Log_(.
)”
target-column: “c_table”
extract-schema:
schema-regexp: “(.)"
target-column: “c_schema”
extract-source:
source-regexp: "(.
)”
target-column: “c_source”
route-log_all:
schema-pattern: “China_Log”
target-schema: downStream
【遇到的问题:问题现象及影响】
现在的问题是,同步当天和存量的数据都没有问题,当过天后。上游生成了新的表,dm同步就会报错,类似下面这种:
“Message”: “startLocation: [position: (mysql-bin|000001.000001, 4540655), gtid-set: 00000000-0000-0000-0000-000000000000:0], endLocation: [position: (mysql-bin|000001.000001, 4540774), gtid-set: 00000000-0000-0000-0000-000000000000:0]: gen insert sqls failed, sourceTable: China_Log.Log_2023_04_27, targetTable: downStream.Log_date: Column count doesn’t match value count: 20 (columns) vs 23 (values)”,
提示新表到下游汇总表的少了三个字段,然后就没有办法继续同步了。
我想知道这种情况如何解决?

建表使用的语句是create table if not exists么,把表结构和这段二进制日志的sql打出来看下吧,另外把dm路由配置截图吧,感觉有些转换了

没有使用create table if not exists。
上游表sql:
CREATE TABLE Log_2023_04_27 (
Id int(11) NOT NULL AUTO_INCREMENT,
Uid int(11) DEFAULT NULL ,
Type int(11) DEFAULT NULL ,
ItemId int(11) DEFAULT NULL ,
UserCardId bigint(15) DEFAULT NULL ,
CardId int(11) DEFAULT NULL ,
MasterUserCardId bigint(15) NOT NULL DEFAULT ‘0’ ,
MasterCardId int(11) NOT NULL DEFAULT ‘0’ ,
Exp int(11) DEFAULT NULL ,
Level tinyint(4) DEFAULT NULL ,
UpdateTime datetime DEFAULT NULL ,
BeforeSkillNew int(11) NOT NULL DEFAULT ‘0’,
SkillNew int(11) NOT NULL DEFAULT ‘0’,
SuppleSkill int(11) NOT NULL DEFAULT ‘0’,
Evolution tinyint(4) NOT NULL DEFAULT ‘0’,
WashTime int(11) NOT NULL DEFAULT ‘0’,
ContractCondition int(11) NOT NULL DEFAULT ‘0’,
ForgeProcess int(11) NOT NULL DEFAULT ‘0’,
EquipType int(11) NOT NULL DEFAULT ‘0’,
SeniorWashTimes int(11) NOT NULL DEFAULT ‘0’,
PRIMARY KEY (Id),
KEY usercardlog_uid (Uid),
KEY type_index (Type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
下游表sql:
CREATE TABLE Log_date (
Id int(11) NOT NULL AUTO_INCREMENT,
Uid int(11) DEFAULT NULL,
Type int(11) DEFAULT NULL ,
ItemId int(11) DEFAULT NULL ,
UserCardId bigint(15) DEFAULT NULL ,
CardId int(11) DEFAULT NULL ,
MasterUserCardId bigint(15) NOT NULL DEFAULT ‘0’ ,
MasterCardId int(11) NOT NULL DEFAULT ‘0’ ,
Exp int(11) DEFAULT NULL ,
Level tinyint(4) DEFAULT NULL ,
UpdateTime datetime DEFAULT NULL ,
BeforeSkillNew int(11) NOT NULL DEFAULT ‘0’,
SkillNew int(11) NOT NULL DEFAULT ‘0’,
SuppleSkill int(11) NOT NULL DEFAULT ‘0’,
Evolution tinyint(4) NOT NULL DEFAULT ‘0’,
WashTime int(11) NOT NULL DEFAULT ‘0’,
ContractCondition int(11) NOT NULL DEFAULT ‘0’,
ForgeProcess int(11) NOT NULL DEFAULT ‘0’,
EquipType int(11) NOT NULL DEFAULT ‘0’,
SeniorWashTimes int(11) NOT NULL DEFAULT ‘0’,
c_table varchar(100) COLLATE utf8_general_ci NOT NULL COMMENT ‘上游表名’,
c_schema varchar(100) COLLATE utf8_general_ci NOT NULL COMMENT ‘上游库名’,
c_source varchar(100) COLLATE utf8_general_ci NOT NULL COMMENT ‘上游数据源名’,
PRIMARY KEY (Id,c_table,c_schema,c_source) /*T![clustered_index] NONCLUSTERED */,
KEY usercardlog_uid (Uid),
KEY type_index (Type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci /*T! SHARD_ROW_ID_BITS=3 PRE_SPLIT_REGIONS=2 */ ;
路由配置:
mysql-instances:

  • source-id: t1
    meta: null
    filter-rules:
    • filter-01
      column-mapping-rules: []
      route-rules:
    • route-UserCardLog
    • route-UserCardLog_all
      block-allow-list: balist-01
      routes:
      route-UserCardLog:
      schema-pattern: “China_Log”
      table-pattern: “Log_"
      target-schema: downStream
      target-table: “Log_date”
      extract-table:
      table-regexp: "UserCardLog_(.
      )”
      target-column: “c_table”
      extract-schema:
      schema-regexp: “(.)"
      target-column: “c_schema”
      extract-source:
      source-regexp: "(.
      )”
      target-column: “c_source”
      route-UserCardLog_all:
      schema-pattern: “China_Log”
      target-schema: card
      filters:
      filter-01:
      schema-pattern: “China_"
      table-pattern: "

      events:
      • create database
      • drop database
      • create table
      • create index
      • drop table
      • truncate table
      • rename table
      • drop index
        action: Ignore
        block-allow-list:
        balist-01:
        do-dbs:
      • “China_Log”
        ignore-tables: []
        ignore-dbs: []

原本的路由文件非常长,目前把这个表单独做到一个任务里面去,再观察一下。可能受到了其他router/block-allow-list配置的影响。

1 个赞

补充一下,下游建表没有使用create table if not exists,但是上游建表使用了create table if not exists。
和这个有关系吗?

额,我说的就是上游,很早以前有个create table if not exists的bug,你可以试试不用if not exists看看
dm同步时候的bug - #11,来自 lance6716.

2 个赞

就是这个原因了。非常感谢。

后续处理,可以使用tiup dmctl binlog-schema list -s source_name taskname db_name table_name_20230427,tiup dmctl binlog-schema list -s source_name taskname db_name table_name_20230428
对比可以发现使用create table if not exists以后造成这两个binlog scheme不一致。
上游不能修改建表语句的情况下,可以使用tiup dmctl binlog-schema update -s source_name taskname db_name table_name_20230428 正确的表结构.sql
更新binlog schema以后,可以继续进行同步。未见数据丢失。
至此问题解决。

1 个赞

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。