下游 TiDB 表结构有更多列的迁移场景
本文介绍如何在下游 TiDB 表结构比上游存在更多列的情况下,使用 DM 对表进行迁移。
数据源表
本文档示例所用的数据源实例如下所示:
Schema | Tables |
---|---|
user | information, log |
store | store_bj, store_tj |
log | messages |
迁移要求
在 TiDB 中定制创建表 log.messages
,其表结构包含数据源中 log.messages
表的所有列,且比数据源的表结构有更多的列。在此需求下,将数据源表 log.messages
迁移到 TiDB 集群的表 log.messages
。
只迁移数据源增量数据到 TiDB ,并且下游 TiDB 表结构有更多列的场景问题处理
如果该迁移任务包含全量数据迁移,迁移任务可以正常运行;但是如果你使用其他方式进行了全量迁移,只是用 DM 进行增量数据复制,可以参考只迁移数据源增量数据到 TiDB创建数据迁移任务,同时还需手动在 DM 中设置用于解析 MySQL binlog 的表结构。
否则,创建任务后,运行 query-status
会返回类似如下数据迁移错误:
"errors": [
{
"ErrCode": 36027,
"ErrClass": "sync-unit",
"ErrScope": "internal",
"ErrLevel": "high",
"Message": "startLocation: [position: (mysql-bin.000001, 2022), gtid-set:09bec856-ba95-11ea-850a-58f2b4af5188:1-9 ], endLocation: [position: (mysql-bin.000001, 2022), gtid-set: 09bec856-ba95-11ea-850a-58f2b4af5188:1-9]: gen insert sqls failed, schema: log, table: messages: Column count doesn't match value count: 3 (columns) vs 2 (values)",
"RawCause": "",
"Workaround": ""
}
]
出现以上错误的原因是 DM 迁移 binlog event 时,如果 DM 内部没有维护对应于该表的表结构,则会尝试使用下游当前的表结构来解析 binlog event 并生成相应的 DML 语句。如果 binlog event 里数据的列数与下游表结构的列数不一致时,则会产生上述错误。
此时,我们可以使用 operate-schema
命令来为该表指定与 binlog event 匹配的表结构。如果你在进行分表合并的数据迁移,那么需要为每个分表按照如下步骤在 DM 中设置用于解析 MySQL binlog 的表结构。具体操作为:
为数据源中需要迁移的表
log.messages
指定表结构,表结构需要对应 DM 将要开始同步的 binlog event 的数据。将对应的CREATE TABLE
表结构语句并保存到文件,例如将以下表结构保存到log.messages.sql
中。CREATE TABLE `messages` ( `id` int(11) NOT NULL, `message` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) )使用
operate-schema
命令设置表结构(此时 task 应该由于上述错误而处于Paused
状态)。tiup dmctl --master-addr <master-addr> operate-schema set -s mysql-01 task-test -d log -t message log.message.sql使用
resume-task
命令恢复处于Paused
状态的任务。使用
query-status
命令确认数据迁移任务是否运行正常。