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

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 个赞