mydumper导出全量数据,怎么获取dump下来的数据的最新的commitTs?

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。

  • 【TiDB 版本】:v3.0.1
  • 【问题描述】:

现需要将运行中(不断有数据写入)的tidb中的数据通过全量(mydumper,loader) + 增量 (drainer)的方式备份到下游的rds中,我如何知道我当前dump出来的文件最新的commitTs是多少,然后我好在drainer中配置initial_commit_ts

  1. 需要调整好 tidb 的 gc 时间 。 详细可以参考: https://pingcap.com/docs-cn/stable/reference/tools/mydumper/#mydumper-备份-tidb-数据报错-gc-life-time-is-shorter-than-transaction-duration-应该怎么解决
  2. 使用 binlogctl 工具生成 Drainer 初次启动所需的 tso 信息 : cd /home/tidb/tidb-ansible && resources/bin/binlogctl -pd-urls=http://127.0.0.1:2379 -cmd generate_meta
  3. mydumper 备份的时候指定 -z 的参数带入第二部获取到的 tso

3.mydumper 备份的时候指定 -z 的参数带入第二部获取到的 tso 这条不是很懂,求详细说明:grinning:

可以直接使用mydumper dump出来的metadata中的Pos吗?

`

Started dump at: 2019-11-04 14:26:52
SHOW MASTER STATUS:
Log: tidb-binlog
Pos: 412312879167176706
GTID:

Finished dump at: 2019-11-04 14:26:59
`

先获取 initial_commit_ts 再用 mydumper 导出。上面提及的 第2步获取的是 initial_commit_ts 。再用 mydumper -z {initial_commit_ts} 带上这个 就可以了。

大佬,顺便问一下,如果我有两个drainer,其中一个同步正常,另外一个同步遗漏数据了,现在我想把遗漏数据的那个drainer的数据,全量和增量重新做一次,看官网上说需要把下游rds的tidb_binlog中的checkpoint表给删掉,现在我只想针对有数据遗漏的drainer进行操作,没有问题的drainer,我不想影响到它,这个需要怎么弄?

意思是多个 Drainer 对应同一个 MySQL 的下游吗? 这样的话可以通过以下步骤。

  1. 到问题的 Drainer 的所在的 TIDB 集群。通过 {tidb_ansible_paht} /resource/bin/pd-ctl -u http://{pd_ip}:{pd_port} cluster 获取 cluster id
  2. 确认该 Cluster_id 只有一个 Drainer 在用。意思是该集群只有一套 Drainer 。可以通过 show drainer status 查看。
  3. 满足第2步的情况下, 根据获取的 cluster_id 到下游的 checkpoint 表清理该行数据。delete from tidb_binlog.checkpoint where clusterid = {cluster_id} (切记先备份该内容)
  4. 重新全量 + 增量部署 Drainer 。

我的业务场景是这样的: 我们生产只有一套tidb集群,tidb之前有一个库A,我开了一个drainer A备份数据到下游实例instance I的库A中,现在我又上线另外一个库B到相同的tidb实例,然后我又开了一个drainer B备份数据到下游实例 instance I的库B中,但是我发现tidb_binlog中的checkpoint表中只有一个commit_ts,然后其中一个drainer由于大表ddl导致invalid connection后,就不同步数据了,我./stop_drainer.sh无法停掉,接着我就kill -9 有问题的drainer进程id,再./start_drainer.sh,有问题drainer启动后,它会直接从另外一个正常drainer当前同步的时间点开始同步,然后就遗漏数据了

我这种情况如果同一个tidb集群中的两个库,如果使用同一个drainer应该就不会产生这种问题?

对的。同一个 TiDB 集群用用一个 Drainer 同步到下游即可。

那像我说的我们生产的那种场景的话,需要怎么防止同样的情况发生呢?

如果需要要同一套 TiDB 对应不同的 Drainer 的话。需要指定 不同的 [syncer.to.checkpoint] 用于区分不同的 Drainer 的 checkpoint 即可。

好的,明白,现在数据我又重新全量+增量弄了一份,但是两个drainer的checkpoint schema是相同,如果下次出现大表ddl的话,还是有可能导致这种情况出现,有没有什么比较简单的办法,不需要重新做dumper和loader的,然后我把drainer的syncer.to.checkpoint修改一下为不同的,之后将initial_commit_ts设置为一个比较早的时间开始同步(中间会有部分已经同步过去的数据),然后再同步可以吗?

initial_commit_ts 可以通过报错的 日志看下能否找到,最后一次正常同步的 commit_ts。然后指定 synced.to.checkpoint 为新的 schema 。开启 safe-mode 应该是可以的。

好的,谢谢大佬

大佬,开启safe mode对业务数据没有影响吧,drainer可以随时中断吧,比如同步./stop_drainer.sh或者kill -9,然后再./start_drainer.sh,因为下游是有记录最新一次的同步commit_ts的

safe mode 会使写下游 MySQL/TiDB 可被重复写入 会用 replace 替换 insert 语句,用 delete + replace 替换 update 语 由于你现在的 checkpoint 并不确定。所以需要打开 safe_mode 来防止指定的 checkpoint 比实际数据的 checkpoint 早导致的重复写入的问题。后续待正常同步后可以把该参数关掉。