TiDB Bug List=

[Critical bug] Log Backup 在遇到 TiKV 重启后可能会遗落数据

大家好,

我们新发现了一个TiDB 的“TiKV BR”组件相关 critical bug,详细见下:

产品 TiDB
组件 TiKV BR
版本 6.5.4 7.1.0 7.1.1 7.4.0 7.2.0 7.3.0 7.1.2 7.5.0 6.5.6 7.1.3 6.5.5 7.1.4 7.5.1 7.6.0 6.5.7 6.5.8 8.0.0 6.5.9
分类 Developer
标签 KnowIssue
来源

Issue

https://github.com/tikv/tikv/issues/16809

Root Cause

TiKV 在日志备份的时候会启动两个并行的进程:

  1. 一个用于将文件推送到下游,这个进程会监听 raftstore 的变更,并将其缓存到本地。
  2. 一个用于推进备份的进度,这个进程会从 PD 不断地获取最新的 TSO,并且用它计算备份最新的进度。

在进程 (1) 积攒了足够多的文件之后,它会将当前缓存的文件上传到外部存储。在此之后,它会从 (2) 中获得当前的进度,并且更新到 PD 上。

但是,在 (1) 将文件上传到外部存储的过程中,新的写入将会持续进入,并且被计入进度计算;问题出现在这里:**这些新的写入不会在当前批次中被上传到外部存储。**因此,假如 (2) 在 (1) 上传文件的过程中,计算了最新的进度,那么这个进度其实是“超前”的。

一般情况下,这些写入会和下一批一起被上传,此时这个“超前”的进度并不会造成严重的后果。但是,如果 TiKV 此时因故重启,这批数据就会丢失。如果此时全局 Checkpoint 已经推进,其他 TiKV 在成为 Leader 之后会从这个“超前”的进度开始日志备份。此时前面提到那些未被备份的数据将永远不会被备份。

[1,Flush] [2,calculate progress]

TS --------------|----------|-------->

^ ^

| ± …but the log backup believes we have backed up to here

± Writes was actually backed up to here…

目前触发概率没有很精准的方式估算,但是总体上看,触发概率:

  • 随着 Flush 花费时间的上升上升
  • 随着 TiKV 数量上升下降。(因为有更多 TiKV 的时候,全局 checkpoint 被某个 TiKV 卡住的概率会变大。)

考虑到 TiKV 重启并不常见,而且目前 PiTR 本身也要求周期性重新全量备份,总体上看这个 bug 触发概率并不算高。

Diagnostic Steps

目前在备份集群没有很好的手段来发现这个问题。

这个问题遗失数据一个比较明显的特征是,那些被遗失的数据在某次进度更新之前,大约几百毫秒内的写入的。可以通过检查数据行的时间戳或者通过 TiDB HTTP API 查询 MVCC 版本确认。

Resolution

触发之后增量备份的部分数据会丢失,目前无法找回。

建议参考 workaround 部分或者升级到不受影响的版本。(6.5.10, 7.1.5, 7.5.2, 或者更高的 LTS 版本。)

以下 LTS 版本受到了影响:

  • Release 6.5: 6.5.4~6.5.9
  • Release 7.1: 7.1.0~7.1.4
  • Release 7.5: 7.5.0~7.5.1

Workaround

在上游集群,可以设置 log-backup.min-ts-interval (这个配置项没有文档)到大于全量备份间隔的值(例如,365d)来解决这个问题;但代价是 RPO 可能在 Leader Transfer 比较频繁的情况下会低于预期。

1 个赞