Native Flashback功能可以通过SQL语句查询或恢复指定时间点的数据,保证在误操作后可以快速获取历史数据。
功能说明
数据库运维过程中的误操作可能会给业务带来严重的影响,常见的恢复手段Binlog Flashback操作较为复杂、容易出错且耗时较长,而通过备份集恢复则需要额外的系统资源,在数据量较大时恢复时间不可控。
PolarDB-X标准版在InnoDB引擎上设计和实现了Native Flashback功能,无需复杂的恢复操作,通过简单的SQL语句即可查询或恢复误操作前的历史数据,节省了大量宝贵的时间,保证业务平稳运行。
前提条件
实例版本要求:PolarDB-X标准版,引擎为MySQL 8.0。
注意事项
仅支持使用InnoDB引擎的表。
需要消耗额外的undo表空间,可以通过
innodb_undo_space_supremum_size
参数进行配置。Native Flashback的查询结果取最接近指定时间点的数据,不保证查询到的数据与指定时间点的数据完全匹配。
暂不支持跨DDL操作的历史版本数据查询和恢复。例如您无法通过Native Flashback查询某个已经被删除的表的内容。
语法
Native Flashback提供了全新的AS OF语法,通过该语法指定需要回滚的时间。语法规则如下:
SELECT ... FROM <表名>
AS OF TIMESTAMP <表达式>;
其中,在表达式中指定回滚的时间,该表达式支持多种形式,示例:
SELECT ... FROM tablename
AS OF TIMESTAMP '2020-11-11 00:00:00';
SELECT ... FROM tablename
AS OF TIMESTAMP now();
SELECT ... FROM tablename
AS OF TIMESTAMP (SELECT now());
SELECT ... FROM tablename
AS OF TIMESTAMP DATE_SUB(now(), INTERVAL 1 minute);
参数说明
Native Flashback功能开放了如下可配置参数:
参数名称 | 说明 |
innodb_rds_flashback_task_enabled |
说明 关闭Native Flashback功能时,需要同步将innodb_undo_retention参数设置为0。 |
innodb_undo_retention |
说明 该参数的值越大,Native Flashback支持的回档查询时间越长,同时undo表空间占用的存储空间也会增加。 innodb_rds_flashback_task_enabled参数设置为OFF时,需同步将本参数设置为0。 |
innodb_undo_space_supremum_size |
|
innodb_undo_space_reserved_size |
说明 该参数的值太大可能导致undo历史记录过多,影响实例性能。如非必要,请保持该参数为0。 |
使用示例
# 获取时间点
MySQL [mytest]> select now();
+---------------------+
| now() |
+---------------------+
| 2020-10-14 15:44:09 |
+---------------------+
1 row in set (0.00 sec)
# 查看数据
MySQL [mytest]> select * from mt1;
+----+------+
| id | c1 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.00 sec)
# 不带WHERE条件的更新操作
MySQL [mytest]> update mt1 set c1 = 100;
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5 Changed: 5 Warnings: 0
MySQL [mytest]> select * from mt1;
+----+------+
| id | c1 |
+----+------+
| 1 | 100 |
| 2 | 100 |
| 3 | 100 |
| 4 | 100 |
| 5 | 100 |
+----+------+
5 rows in set (0.00 sec)
# 查询历史时间点的数据,成功返回结果
MySQL [mytest]> select * from mt1 AS OF timestamp '2020-10-14 15:44:09';
+----+------+
| id | c1 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.00 sec)
# 如果超出保留的历史数据范围,返回失败
MySQL [mytest]> select * from mt1 AS OF timestamp '2020-10-13 14:44:09';
ERROR 7545 (HY000): The snapshot to find is out of range
# 开始恢复数据
MySQL [mytest]> create table mt1_tmp like mt1; # 创建一个与原表结构相同的临时表
Query OK, 0 rows affected (0.03 sec)
MySQL [mytest]> insert into mt1_tmp
-> select * from mt1 AS OF
-> TIMESTAMP '2020-10-14 15:44:09'; # 将原表中的历史数据写入临时表
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
MySQL [mytest]> select * from mt1_tmp; # 确认临时表中的数据是否正确
+----+------+
| id | c1 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.00 sec)
MySQL [mytest]> rename table mt1 to mt1_bak,
-> mt1_tmp to mt1; #(进行本操作需要先停止业务读写)更改原表表名为mt1_bak,并将临时表名改成原表表名,完成数据恢复
Query OK, 0 rows affected (0.02 sec)
MySQL [mytest]> select * from mt1; # 确认恢复完成后的数据
+----+------+
| id | c1 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.01 sec)