断点恢复

快照恢复或日志恢复会因为一些可恢复性错误导致提前结束,例如硬盘空间占满、节点宕机等等一些突发情况。在 TiDB v7.1.0 之前,在错误被处理之后,之前恢复的进度会作废,你需要重新进行恢复。对大规模集群来说,会造成大量额外成本。

为了尽可能继续上一次的恢复,从 TiDB v7.1.0 起,备份恢复特性引入了断点恢复的功能。该功能可以在意外中断后保留上一次恢复的大部分进度。

使用场景

如果你的 TiDB 集群规模很大,无法接受恢复失败后需要重新恢复的情况,那么,你可以使用断点恢复功能重试恢复。br 工具会定期记录已恢复的分片,使得在下一次重试恢复时回到离上一次退出时较近的进度。

实现原理

断点恢复的实现原理分为快照恢复和日志恢复两部分。

快照恢复

快照恢复的实现原理与快照备份类似,br 工具会批量恢复一段键范围 (Region) 内的所有的 SST 文件。恢复完成后,br 工具记录下这段范围以及该范围对应的恢复集群的表 ID。断点恢复功能会定期将这些新增的相关恢复信息上传至外部存储中,从而持久化存储该恢复任务已完成的键范围。

在重试恢复时,br 工具会从外部存储读取已经恢复的键范围,并匹配相关的表 ID。在恢复过程中,会跳过与断点恢复记录的键范围重叠且对应表 ID 相同的范围。

如果在重试恢复前,你删除了某些表,那么重试恢复时新创建的表的 ID 会与之前记录在断点恢复的表 ID 不同,从而绕过使用之前的断点恢复信息,重新恢复该表,也就是说,新的 ID 的同个表可以不使用旧的 ID 的断点恢复信息,而是重新记录新 ID 对应的断点恢复信息。

由于数据采用了 MVCC(多版本并发控制)机制,带有固定 TS 的数据可以被无序且重复写入。

快照恢复在恢复库表 DDL 时添加了 ifExists 参数。对于已经存在的库表(视为已经创建完毕),br 工具会自动跳过恢复。

日志恢复

日志恢复需要按照时间顺序恢复 TiKV 节点备份下来的数据元信息 (meta-kv)。断点恢复首先会根据 meta-kv 数据为备份集群和恢复集群建立一一对应的 ID 映射关系,以确保在不同重试恢复过程中 meta-kv 的 ID 保持一致。这样,meta-kv 就具备了重新恢复的能力。

与快照备份文件不同,日志备份文件的范围可能会重叠,因此无法直接使用键范围作为恢复进度的元信息。同时,日志备份文件数量可能非常多。不过,每个日志备份文件在日志备份元信息中的位置是固定的,因此可以为每个日志备份文件指定一个日志备份元信息中唯一的位置作为恢复进度的元信息。

日志备份元信息中包含一个存放文件元信息的数组。数组中的每个文件元信息代表一个由多个日志备份文件拼接而成的文件。文件元信息记录了这些日志备份文件在拼接文件中的偏移和大小。因此,br 工具可以使用三元组 (日志备份元信息名,文件元信息数组偏移,日志备份文件数组偏移) 来唯一标识一个日志备份文件。

使用限制

断点恢复功能依赖于 GC 机制,且无法记录所有已恢复的数据,具体描述如下。

GC 会被停止

在日志恢复过程中,日志数据恢复的顺序是无序的,因此可能会出现一个 key 的删除记录优先于该 key 的写入记录恢复的情况。如果此时触发 GC,该 key 的所有数据会被删除,导致该 key 后续恢复的写入记录无法被 GC 处理。为了避免这种情况,br 命令行工具会在日志恢复过程中暂停 GC。当 br 工具中途退出后,GC 将仍然保持暂停状态。

日志恢复完成后会重新启动 GC,不需要手动启动。但如果你不想再继续恢复时,请手动开启 GC,开启方法如下:

br 工具暂停 GC 的原理是通过执行 SET config tikv gc.ratio-threshold = -1.0,将 gc.ratio-threshold 的值设置成负数来暂停 GC。你可以通过修改 gc.ratio-threshold 的值手动开启 GC,例如执行 SET config tikv gc.ratio-threshold = 1.1 将参数重置为默认值。

部分数据需要重新恢复

在重试恢复时,部分已恢复的数据可能需要重新恢复,包括正在恢复的数据和还未被断点记录的数据。

  • 由错误引起的退出,br 工具会在退出前将已恢复的数据元信息持久化到外部存储中,因此只有正在恢复的数据需要在下一次重试中重新恢复。

  • 如果 br 工具进程被系统中断,那么 br 将无法把已恢复的数据元信息持久化到外部存储中。br 工具持久化已恢复的数据元信息的周期为 30 秒,因此大约最近 30 秒内的已完成恢复的数据无法持久化到外部存储,在下次重试时需要重新恢复。

不要在恢复期间修改集群数据

在恢复失败后,请避免向集群写入或删除数据、删除或创建表。由于备份数据中可能包含重命名表的 DDL 操作,断点恢复无法确认被删除的表或已存在的表是否是外部操作引起的,这会影响下次重试恢复的准确性。