下游 TiDB 表结构有更多列的迁移场景

    本文档示例所用的数据源实例如下所示:

    在 TiDB 中定制创建表 ,其表结构包含数据源中 log.messages 表的所有列,且比数据源的表结构有更多的列。在此需求下,将数据源表 log.messages 迁移到 TiDB 集群的表 log.messages

    下面介绍满足以上迁移要求的具体操作步骤。

    假设在开始进行数据迁移时,数据源表结构为:

    1. CREATE TABLE `messages` (
    2. `id` int(11) NOT NULL,
    3. `message` varchar(255) DEFAULT NULL,
    4. `annotation` varchar(255) DEFAULT NULL,
    5. PRIMARY KEY (`id`)
    6. )

    创建数据迁移任务

    1. 创建任务配置文件 task.yaml,配置增量同步模式,以及每个数据源的同步起点。完整的任务配置文件示例如下:

      1. name: task-test # 任务名称,需要全局唯一
      2. task-mode: all # 进行全量数据迁移 + 增量数据迁移
      3. ## 配置下游 TiDB 数据库实例访问信息
      4. target-database: # 下游数据库实例配置
      5. host: "127.0.0.1"
      6. port: 4000
      7. user: "root"
      8. password: "" # 如果密码不为空,则推荐使用经过 dmctl 加密的密文
      9. ## 使用黑白名单配置需要同步的表
      10. block-allow-list: # 数据源数据库实例匹配的表的 block-allow-list 过滤规则集,如果 DM 版本早于 v2.0.0-beta.2 则使用 black-white-list
      11. do-dbs: ["log"] # 迁移哪些库
      12. ## 配置数据源
      13. mysql-instances:
      14. - source-id: "mysql-01" # 数据源对象 ID,可以从数据源配置中获取
      15. block-allow-list: "bw-rule-1" # 引入上面黑白名单配置
      16. syncer-config-name: "global" # 引用上面的 syncers 增量数据配置
      17. meta: # `task-mode` 为 `incremental` 且下游数据库的 `checkpoint` 不存在时 binlog 迁移开始的位置; 如果 `checkpoint` 存在,以 `checkpoint` 为准
      18. binlog-name: "mysql-bin.000001"
      19. binlog-pos: 2022
      20. binlog-gtid: "09bec856-ba95-11ea-850a-58f2b4af5188:1-9"
    2. 使用 start-task 命令创建同步任务:

      1. {
      2. "result": true,
      3. "msg": "",
      4. "sources": [
      5. {
      6. "result": true,
      7. "msg": "",
      8. "source": "mysql-01",
      9. "worker": "127.0.0.1:8262"
      10. ]
      11. }
    3. 使用 query-status 查看同步任务,确认无报错信息:

    如果该迁移任务包含全量数据迁移,迁移任务可以正常运行;但是如果你使用其他方式进行了全量迁移,只是用 DM 进行增量数据复制,可以参考创建数据迁移任务,同时还需手动在 DM 中设置用于解析 MySQL binlog 的表结构。

    否则,创建任务后,运行 query-status 会返回类似如下数据迁移错误:

    1. "errors": [
    2. {
    3. "ErrCode": 36027,
    4. "ErrClass": "sync-unit",
    5. "ErrScope": "internal",
    6. "ErrLevel": "high",
    7. "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)",
    8. "RawCause": "",
    9. "Workaround": ""
    10. }
    11. ]

    此时,我们可以使用 operate-schema 命令来为该表指定与 binlog event 匹配的表结构。如果你在进行分表合并的数据迁移,那么需要为每个分表按照如下步骤在 DM 中设置用于解析 MySQL binlog 的表结构。具体操作为:

    1. 为数据源中需要迁移的表 log.messages 指定表结构,表结构需要对应 DM 将要开始同步的 binlog event 的数据。将对应的 CREATE TABLE 表结构语句并保存到文件,例如将以下表结构保存到 log.messages.sql 中。

      1. CREATE TABLE `messages` (
      2. `id` int(11) NOT NULL,
      3. `message` varchar(255) DEFAULT NULL,
      4. PRIMARY KEY (`id`)
      5. )
    2. 使用 命令设置表结构(此时 task 应该由于上述错误而处于 Paused 状态)。

    3. 使用 resume-task 命令恢复处于 Paused 状态的任务。

    4. 使用 命令确认数据迁移任务是否运行正常。