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 的变更,并将其缓存到本地。

一个用于推进备份的进度,这个进程会从 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 个赞