BR 增量恢复失败

【 TiDB 使用环境】生产\测试环境\ POC
生产
【 TiDB 版本】
4.0.15
【遇到的问题】
增量恢复出现唯一键冲突

  [2022/06/23 19:01:40.184 +08:00] [ERROR] [db.go:81] ["execute ddl query failed"] [query="ALTER TABLE `supplier_environment_total` ADD UNIQUE `uk_key_code`(`key_code`)"] [db=supply_chain_factory] [historySchemaVersion=2360] [error="[kv:1062]Duplicate entry '' for key 'uk_key_code'"] [errorVerbose="[kv:1062]Duplicate entry '' for key 'uk_key_code'\
github.com/pingcap/errors.AddStack\
\tgithub.com/pingcap/errors@v0.11.5-0.20201126102027-b0a155152ca3/errors.go:174\
github.com/pingcap/errors.Trace\
\tgithub.com/pingcap/errors@v0.11.5-0.20201126102027-b0a155152ca3/juju_adaptor.go:15\
github.com/pingcap/tidb/ddl.(*ddl).doDDLJob\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/ddl/ddl.go:578\
github.com/pingcap/tidb/ddl.(*ddl).CreateIndex\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/ddl/ddl_api.go:4034\
github.com/pingcap/tidb/ddl.(*ddl).AlterTable\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/ddl/ddl_api.go:2117\
github.com/pingcap/tidb/executor.(*DDLExec).executeAlterTable\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/executor/ddl.go:366\
github.com/pingcap/tidb/executor.(*DDLExec).Next\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/executor/ddl.go:86\
github.com/pingcap/tidb/executor.Next\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/executor/executor.go:262\
github.com/pingcap/tidb/executor.(*ExecStmt).handleNoDelayExecutor\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/executor/adapter.go:531\
github.com/pingcap/tidb/executor.(*ExecStmt).handleNoDelay\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/executor/adapter.go:413\
github.com/pingcap/tidb/executor.(*ExecStmt).Exec\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/executor/adapter.go:366\
github.com/pingcap/tidb/session.runStmt\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/session/tidb.go:322\
github.com/pingcap/tidb/session.(*session).ExecuteStmt\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/session/session.go:1381\
github.com/pingcap/tidb/session.(*session).ExecuteInternal\
\tgithub.com/pingcap/tidb@v1.1.0-beta.0.20210714111333-67b641d5036c/session/session.go:1132\
github.com/pingcap/br/pkg/gluetidb.(*tidbSession).Execute\
\tgithub.com/pingcap/br@/pkg/gluetidb/glue.go:109\
github.com/pingcap/br/pkg/restore.(*DB).ExecDDL\
\tgithub.com/pingcap/br@/pkg/restore/db.go:79\
github.com/pingcap/br/pkg/restore.(*Client).ExecDDLs\
\tgithub.com/pingcap/br@/pkg/restore/client.go:500\
github.com/pingcap/br/pkg/task.RunRestore\
\tgithub.com/pingcap/br@/pkg/task/restore.go:292\
main.runRestoreCommand\
\tgithub.com/pingcap/br@/cmd/br/restore.go:25\
main.newFullRestoreCommand.func1\
\tgithub.com/pingcap/br@/cmd/br/restore.go:97\
github.com/spf13/cobra.(*Command).execute\
\tgithub.com/spf13/cobra@v1.0.0/command.go:842\
github.com/spf13/cobra.(*Command).ExecuteC\
\tgithub.com/spf13/cobra@v1.0.0/command.go:950\
github.com/spf13/cobra.(*Command).Execute\
\tgithub.com/spf13/cobra@v1.0.0/command.go:887\
main.main\
\tgithub.com/pingcap/br@/cmd/br/main.go:56\
runtime.main\
\truntime/proc.go:203\
runtime.goexit\
\truntime/asm_amd64.s:1357"] [stack="github.com/pingcap/br/pkg/restore.(*DB).ExecDDL\
\tgithub.com/pingcap/br@/pkg/restore/db.go:81\
github.com/pingcap/br/pkg/restore.(*Client).ExecDDLs\
\tgithub.com/pingcap/br@/pkg/restore/client.go:500\
github.com/pingcap/br/pkg/task.RunRestore\
\tgithub.com/pingcap/br@/pkg/task/restore.go:292\
main.runRestoreCommand\
\tgithub.com/pingcap/br@/cmd/br/restore.go:25\
main.newFullRestoreCommand.func1\
\tgithub.com/pingcap/br@/cmd/br/restore.go:97\
github.com/spf13/cobra.(*Command).execute\
\tgithub.com/spf13/cobra@v1.0.0/command.go:842\
github.com/spf13/cobra.(*Command).ExecuteC\
\tgithub.com/spf13/cobra@v1.0.0/command.go:950\
github.com/spf13/cobra.(*Command).Execute\
\tgithub.com/spf13/cobra@v1.0.0/command.go:887\
main.main\
\tgithub.com/pingcap/br@/cmd/br/main.go:56\
runtime.main\
\truntime/proc.go:203"]

经排查, BR恢复的时候, 先恢复ddl, 再恢复数据, 这种逻辑在恢复全备是没有问题,但是恢复增备有问题,比如

一个表
t1 做ddl 加列, 默认值是1
t2, 修改默认值, 消除重复重
t3, 加唯一索引

时间关系: t1< t2 < t3

如果先做ddl , 即加执行加列, 然后再加唯一索引,最后再恢复数据 就会现在
唯一键冲突问题。

关于BR 增量恢复我看了一个文章, 4.x, 5.x 是正式功能, 结果到了6.x 就变成试验功能了, 是发现这里面有BUG 吗?

【复现路径】做过哪些操作出现的问题
【问题现象及影响】
【附件】

  • 相关日志、配置文件、Grafana 监控(https://metricstool.pingcap.com/)
  • TiUP Cluster Display 信息
  • TiUP CLuster Edit config 信息
  • TiDB-Overview 监控
  • 对应模块的 Grafana 监控(如有 BR、TiDB-binlog、TiCDC 等)
  • 对应模块日志(包含问题前后 1 小时日志)

若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。

1 个赞

https://docs.pingcap.com/zh/tidb/dev/br-usage-restore#恢复增量备份数据

你备份时指定的last backup ts 对吗?

嗯,指定了last backup ts 就是增备

你这文档不是6.1 才有的吗?6.1把增备弄成了实验特性,5.x 与4.x 并没有

这个描述感觉太简单, 根据原理推测(先执行ddl 然后再执行加载数据,而不是按实际顺序执行), 只是增量期时有dll 操作, 基本上会有问题,比如说加唯一索引等。

原理一样啊, 重点东西都提到啦, 文档越来越完善了

你之前的全备恢复出来后,查看supplier_environment_total表上有 UNIQUE uk_key_code(key_code) 吗?

没有, 这个UNIQUE key 就是在增备期间加的

有大佬 能帮助解答一下 这个问题么?

6.0 之前的文档增量备份功能的状态有遗漏,在 6.1 我们进行了完善了。 非常抱歉,造成误解。

如果先做了 t3, t1 到 t2 之间数据如果有冲突,恢复的的时候肯定会有冲突报错。 你按照时间顺序恢复有问题吗

我可以确定是严格按时间来的,上面的例子
t0 时刻完成了一次全备
t1 加列, 默认值是1
t2 修改默认值, 消除重复重
t3 加唯一索引
t4 增备[t0, t4]之间的数据

恢复时, 先恢复t0时候的时候,这个没有问题, 但是恢复t4时, 由于先做ddl, 即先加列、加唯一索引 然后才导数据, 导致唯一键冲突

BR 增量恢复会执行在增量备份期间发生的 DDL,不需要手动执行。 如果你要执行额外的 DDL,可以选择在增量恢复后执行。 你试试在增量恢复之前不要手动执行 DDL 呢

我没手动执行DDL, DDL都是通过BR 执行的呀。 如果BR 增量期间没有DDL, 逻辑上肯定没有问题。

我想表达的意思就是 增备恢复时, 由BR 增备中的DDL 执行错误,和手动执行没有关系

我从始至终想表达的意思是, 如果增备数据中有ddl 操作, 恢复的时候可能会执行错误。

(PS: 是我表达有问题么 :joy:

  1. 增量备份具体是怎么备份和还原的?从您的说明来看是由于先默认值然后添加唯一索引导致报错。
  2. 根据您的备份和还原时间,我尝试复现一下。(比如 t1,t2,t3 都在一个增量备份里?)
1 个赞

我可以确定是严格按时间来的,上面的例子
t0 时刻完成了一次全备
t1 加列, 默认值是1
t2 修改默认值, 消除重复重
t3 加唯一索引
t4 增备[t0, t4]之间的数据

t0 < t1 < t2 < t3 < t4
恢复时, 先恢复t0时候的时候,这个没有问题, 但是恢复t4时, 由于先做ddl, 即先加列、加唯一索引 然后才导数据, 导致唯一键冲突

这个我本地已经复现了

然后在14:40 全备
接着

alter table unique_test add age int default 1;
update unique_test set age = 2 where id = 1;
update unique_test set age = 3 where id = 3;
alter table unique_test add unique index uni_idx(age);
完成时间在14:45
接着备份14:40 到14:46 分之间的增备
然后依次恢复14:40 全备和14:40 到14:46 分的增备

  1. 我在 v5.4.0 版本可以复现,记录了一个 issue https://github.com/pingcap/br/issues/1471
  2. 原本想着先 drop index 再测试增量备份。但是测试环境 gc 时间到了,没法增量备份。我理解您的生产环境应该gc时间也过了吧?
  3. 目前感觉可能需要重新全量备份了。