为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【TiDB 版本】
tidb版本为v5.0.0
DM版本为v2.0.1
【问题描述】
任务模式为“all”,因为我测试的场景是全量+增量
task.yaml关键配置大致如下:
task-mode: "all"
mysql-instances:
- source-id: "dev-a-mysql-slave-replica"
block-allow-list: "test-rule"
block-allow-list:
test-rule:
do-dbs: ["push"]
do-tables:
- db-name: "push"
tbl-name: "user"
-
此时首次start-task后可以发现user表新建并同步了存量的n条数据。是符合正常期望的
-
之后将 tbl-name: "user"修改为 tbl-name: “abc”,发现下游tidb中并未新建并同步abc表的数据
-
去dm-worker的log文件可看到如下关键日志:
[2021/04/11 08:48:07.904 +00:00] [ERROR] [baseconn.go:106] [“query statement failed”] [task=test] [unit=“binlogreplication”] [query=“SHOW CREATE TABLE push
.user
”] [argument="[]"] [error=“Error 1146: Table ‘push.user’ doesn’t exist”]
[2021/04/11 08:48:07.905 +00:00] [ERROR] [db.go:199] [“query statement failed after retry”] [task=test] [unit=“binlog replication”] [query=“SHOW CREATE TABLE push
.user
”] [argument="[]"] [error="[code=10005:class=database:scope=not-set:level=high], Message: query statement failed: SHOW CREATE TABLE push
.user
, RawCause: Error 1146: Table ‘push.user’ doesn’t exist"]
-
query-status test的结果如下
{
“result”: true,
“msg”: “”,
“sources”: [
{
“result”: true,
“msg”: “”,
“sourceStatus”: {
“source”: “dev-a-mysql-slave-replica”,
“worker”: “dm-10.10.52.20-8262”,
“result”: null,
“relayStatus”: null
},
“subTaskStatus”: [
{
“name”: “test”,
“stage”: “Running”,
“unit”: “Sync”,
“result”: null,
“unresolvedDDLLockID”: “”,
“sync”: {
“totalEvents”: “0”,
“totalTps”: “0”,
“recentTps”: “0”,
“masterBinlog”: “(mysql-bin.000283, 787902482)”,
“masterBinlogGtid”: “72ce558a-7c0c-11e7-8117-fa163eaf8427:244995526-279418205:279418207-279498776:279498778-279505474:279505476-279505568:279505570-279533138:279533140-279536477:279536479-279546364:279546366-279546508:279546510-288522397:288522399-743419229,ddffec79-c444-11e7-9807-fa163ef5cb4b:1-97”,
“syncerBinlog”: “(mysql-bin.000283, 787800006)”,
“syncerBinlogGtid”: “72ce558a-7c0c-11e7-8117-fa163eaf8427:244995526-279418205:279418207-279498776:279498778-279505474:279505476-279505568:279505570-279533138:279533140-279536477:279536479-279546364:279546366-279546508:279546510-288522397:288522399-743419041,ddffec79-c444-11e7-9807-fa163ef5cb4b:1-97”,
“blockingDDLs”: [
],
“unresolvedGroups”: [
],
“synced”: false,
“binlogType”: “remote”
}
}
]
}
]
}
-
此时我手动在tidb去执行create table abc的DDL,再start-task,发现abc表记录同步过来了
【疑问】
我的期望是同步表从user改abc后(或者user也保留,增加一个abc表),能够自动创建abc并其同步存量记录,而目前似乎只有首次start-task的配置的库表才会自动新建? 之后stop-task+改task.yaml文件+start-task的新增库表是无法自动新建的? 能详细阐述下这类用法官方推荐是什么样的吗,谢谢
小王同学
2
先梳理下你这边的步骤
首先同步的是 tbl-name: “user” 同步正常。
停掉同步任务之后,想要同步 tbl-name: “abc” 这个表,但其实上游不存在该表。不存在的表写在 同步任务里是什么样的需求呢 ?
上游不存在的表,配置在 task 中启动,报错 error=“Error 1146: Table ‘push.user’ doesn’t exist 这是预期的行为。
新增表同步可以参考官网
https://docs.pingcap.com/zh/tidb-data-migration/stable/faq#如何为已有迁移任务增加需要迁移的表
谢谢小王同学回答。
上游mysql是存在该表的。提示log中报的应是下游tidb不存在abc表。所以我是说下游tidb在处理abc表时为何没像首次start-task的user表那样自动create并同步数据
小王同学
4
哦 这个问题可以看下下游 dm_meta 的 checkpoint 信息,这个 checkpoint 是全局的,并不是表级别的。比如 在 t1 时间修改 task 新增一个表,该表在 t0 之前创建,重启 task 也只会在 t1 断点续传,从 t1 开始同步 新表的数据,但是 新表的表结构未在下游创建,会导致同步出错。上面 官网链接中也有提到哈。
小王同学,第二种我试了下,还是不行。我说下大致过程:
- 之前task.yaml有user表,而目前abc表有1条记录(如id=1),此时假设binlog_name=mysql-bin.000001 & binlog_position=100。我stop-task
- abc表新增第2条记录(如id=2),假设binlog_name=mysql-bin.000001 & binlog_position=120
- 我在task.yml中新增abc表,增加syncers的safe-mode: true。并且手动在下游tidb执行DDL:create table abc。并且将{task-name}_syncer_checkpoint的is_global=1的唯一的source-id记录,修改其binlog_name=mysql-bin.000001 & binlog_position=100(即步骤1时的值)
- 此时start-task继续开始任务。
此时我的预期是按以上操作后,dm任务能将abc表将id=2的记录同步过来。但是并没有,abc表是空的,然后我在上游mysql新增了第3条记录(id=3)时,下游倒是同步了id=3的记录。
所以是我对文档理解有误吗?我该如何操作呢?
小王同学
8
文档中推荐方式是 先进行全量数据导入,然后再去更新 checkpoint 信息,这样操作看看呢。
相当于新表abc的存量数据,新建1个全量数据导入的taskA来处理。然后在原user表的taskB加上abc表,并且将taskB的is_global所在记录,回退至全量导入任务taskA所在的binlog_name & binlog_position,相当于处理全量taskA后的增量?
还是不行。我说下我的步骤:
-
之前task.yaml有user表,而目前abc表有1条记录(如id=1)。我新建task-abc.yaml(task-mode设为full)全量同步。此时query-status task-abc假设binlog_name=mysql-bin.000001 & binlog_position=100。可以发现abc表id=1的记录同步到tidb了
-
stop-task task.yaml。并且编辑task.yaml增加abc表以及syncers的safe-mode: true。此时假设{task-name}_syncer_checkpoint的is_global=1为binlog_name=mysql-bin.000001 & binlog_position=110。我取较小值binlog_position=100更新到is_global=1记录。
-
此时abc表新增第2条记录(如id=2),start-task task.yaml继续开始任务
此时我的预期是按以上操作后。task任务能将关闭期间abc表新增id=2的记录同步到tidb,最终tidb有id=1和id=2的记录。但是结果是id=2的没有。 此时我在上游mysql新增了第3条记录(id=3)时,下游倒是同步了id=3的记录。
里面出了什么问题,我应该是完全按照文档要求操作了吧
yilong
(yi888long)
12
看描述,没有先全量导入数据吧,不是用你这个task任务,可以重启一个任务导入,或者就简单的dumpling,lightning 导入到 tidb 全量数据就行。
明白,如我最新的这条描述,我已经用新任务成功导入了存量数据id=1了。现在的问题是,全量导入后~旧任务加入新表再start的 期间还有会一些增量数据,我这部分数据用文档的方法没成功同步过来
旧task.yaml停止了的,并且按文档说的回退到了全量同步完成时的binlog_name和binlog_position,再重新start-task 旧task.yaml
yilong
(yi888long)
16
创建task同步表A---->停止task----> 全量导入表B---->修改task,包含表B----> 再启动 task ,是这样吗?如果是,可以重新操作一下。
应该是全量导入表B后,再停task哦,否则task停止时间还得等全量导完B的时间(比如B表是大表要同步5小时,task就得停至少5小时)
官网文档写的意思是停了task后,把task任务的checkpoint回滚到表B全量同步结束时,再启动task任务
小王同学。能帮我确认下是不是{task-name}_syncer_checkpoint中的binlog_gtid也要更新(官网文档只说了binlog_name & binlog_position ),我发现把binlog_gtid也更新,就可以达到我期望效果了!
即之前回滚的sql一直是:
update test_syncer_checkpoint set binlog_name=‘mysql-bin.000285’,binlog_pos = 597648319 where is_global=‘1’;
成功的是回滚sql变成了:
update test_syncer_checkpoint set binlog_name=‘mysql-bin.000285’,binlog_pos = 597648319,binlog_gtid=‘ddffec79-c444-11e7-9807-fa163ef5cb4b:1-97,xxxxxxxxxx’ where is_global=‘1’;
(另外set binlog_gtid=’'或binlog_gtid=null也不行)
开了的,开了回滚步骤时是不是就有涉及is_global的gtid的操作了,还请详细介绍下,官方文档完全没提