数据库内核月报

数据库内核月报 - 2023 / 08

PolarDB MySQL - 库表恢复性能优化

Author: 李畅(巴卡)

背景

用户在使用数据库时,可能会因为误操作导致数据被误修改,或者想要修复某个用户表的数据,PolarDB 提供了多种备份恢复方式,包括实例级别的备份与恢复、库表备份与恢复、表回收站以及Flashback 等。其中实例级别和库表的备份恢复均基于快照,用户可以将实例或者库表恢复为某个时间点的备份。因为备份需要使用额外的存储,默认频率不会很高,如果想要恢复的时间点没有备份,就需要使用这个时间点之前最近的备份集以及redo log恢复到指定的某个时间点;表回收站用于处理误删表的情况,开启表回收站功能后,删除的表不会被立即删除,而是rename 到 recycle bin 下;Flashback 使用undo 回溯到某个时间点,一般是比较近的时间点。用户在做恢复时,需要根据不同的场景选择合适的恢复方法。

云上数据库的库表恢复

MySQL 的 Transportable Tablespace 特性提供了备份以及恢复file_per_table 表的操作。目前各家云厂商提供的库表恢复功能大部分基于该特性实现。简单的备份与恢复流程如下:

上述是使用该特性所做的简单的备份恢复操作,但是在数据量以及业务压力比较大的情况下存在下列问题:

对于第一个问题,PolarDB 底层存储使用PolarStore,可以设置备份策略定期生成备份集,使用ROW(Redirect on Write),不会对同一份数据复制多次。可以直接使用备份集恢复,也可以基于某个备份集和redo log 恢复到指定的时间点。第二个问题是本文接下来部分介绍的优化要解决的。接下来以恢复到指定时间点为例介绍PolarDB 提供的库表恢复功能的流程。

库表恢复流程

恢复到指定时间点

以恢复库表到指定的时间点为例,用户在确定目标库表和要恢复到的时间点之后,恢复任务会拉起一个临时的实例,该实例使用的PolarStore 上的数据是某个备份集的,因为 lsn 和 时间之间存在映射关系,所以恢复到指定的时间点就是用这个临时的实例应用增量redo 直到某个lsn。恢复完成之后,执行flush table ... for export生成导入所需要的.cfg文件。至此,临时实例上的任务就已经完成了,这个临时的实例会在整个恢复任务完成之后释放掉。
临时实例上恢复到指定时间点

原导入流程

通过以上步骤,在临时实例上就包含了目标时间点状态的库表数据,接下来的步骤就是:

一写多读架构库表恢复流程

优化后的导入流程

上述的原有库表恢复流程解决了最开始列出来的第一个问题,但是通过上述时间点恢复的例子可以发现新的问题:

所以为了解决上面两个问题,以及最开始提到的第二个问题,优化后的流程分别通过对恢复流程记录redo log 以及新的load 数据方式解决。这种新的load 数据的特点包括:

库表恢复新流程

总结

新的恢复流程通过记录redo log 解决了RO 和 Standby的同步以及多次恢复的问题,通过引入DDL 使得整个恢复流程是一个原子操作。此外还通过省略多余的IO 操作,整体速度比原流程更快。

参考

如何按备份集恢复误操作的数据库/表_云原生关系型数据库 PolarDB-阿里云帮助中心
如何按时间点恢复的方式恢复库表_云原生关系型数据库 PolarDB-阿里云帮助中心
如何从备份集恢复指定的库或表_云原生关系型数据库 PolarDB-阿里云帮助中心
如何将指定的库或表恢复到过去时间点_云原生关系型数据库 PolarDB-阿里云帮助中心
http://mysql.taobao.org/monthly/2022/07/02/