You need to enable JavaScript to run this app.
导航
Flashback Query for MySQL 8.0
最近更新时间:2025.04.24 16:40:03首次发布时间:2025.04.22 17:22:44
我的收藏
有用
有用
无用
无用

本文介绍云数据库 MySQL 版闪回查询功能的相关信息。

背景信息

在数据库运维过程中可能会发生误操作的情况,这些误操作可能会给业务带来严重的影响,因误操作导致业务受到影响时,常见的恢复手段有回档、克隆等操作,但对于少量的数据变更以及紧急故障修复而言,容易出错且耗时较长,在数据量较大时恢复时间不可控。
云数据库 MySQL 版在 InnoDB 引擎上设计和实现了闪回查询功能,仅通过简单的 SQL 语句即可查询误操作前的历史数据。

参数说明

闪回查询功能的使用依赖于参数 loose_rds_flashback_query 和 loose_rds_flashback_query_window 的配置,这两个参数的信息如下:

名称默认值是否需要重启以生效取值范围级别参数描述

loose_rds_flashback_query

OFF

[ON|OFF]

Global

用于开启或关闭 InnoDB 的闪回查询功能。

loose_rds_flashback_query_window

900

[1-604800]

Global

用于设定支持闪回查询的时间段。

说明

支持闪回查询时间范围的终点只能为当前时间点,即 now()。支持闪回查询时间范围的起点由“闪回查询功能的开启时间”和“保留时间”中的较大值决定:

  • 闪回查询功能的开启时间:开启闪回查询功能的时间点。
  • 保留时间:当前时间减去 loose_rds_flashback_query_window 配置的时间长度,即 now() - loose_rds_flashback_query_window)。

状态说明

云数据库 MySQL 版提供了以下状态来显示当前闪回查询的状态:

名称级别含义

Innodb_flashback_state

Global

闪回查询运行状态

  • DISABLED_AND_PURGED:特性关闭,并且完成 view record 的 purge。

  • ENABLED:特性开启,并且正常运行

  • DISABLED:特性关闭,但是还在 purge 残余的 view record。

  • MISSING_META_TABLE:特性开启,但是元数据表还没创建。

Innodb_flashback_state_code

Global

闪回查询运行状态码

  • 0:DISABLED_AND_PURGED

  • 1:ENABLED

  • 2:DISABLED

  • 3:MISSING_META_TABLE

Innodb_flashback_query_views_table_open_count_by_purge_threadGlobalInnoDB purge thread 打开元数据表的次数。
Innodb_flashback_query_views_table_open_count_by_persist_threadGlobalPersist thread 打开元数据表的次数。

Innodb_flashback_query_views_table_open_count_by_user_thread

Global

User thread 打开元数据表的次数。

Innodb_flashback_query_start_timeGlobal闪回查询支持的时间起点。
Innodb_flashback_query_end_timeGlobal闪回查询支持的时间终点。

注意事项

  • 如果在设置参数 loose_rds_flashback_query 为 ON之前执行闪回查询,系统会返回报错 ERROR 1030 (HY000): Got error 216 - 'Option loose_rds_flashback_query is OFF' from storage engine

  • 如果查询了闪回查询时间范围之外的历史信息,系统会返回报错 ERROR 1030 (HY000): Got error 215 - 'Read view not found; Timestamp may be too old' from storage engine

  • 仅支持 InnoDB 表,不支持 view 及其它引擎,不支持 last_insert_id() 等没有实际列对应的函数。

  • 仅支持在 REPEATABLE READ、 READ COMMITTED 隔离级别下使用闪回查询。关于隔离级别更多信息,可以查看MySQL官方文档 17.7.2.1 Transaction Isolation Levels

  • 不支持在 for update 类型的语句中使用闪回查询,执行会报错 ERROR 1030 (HY000): Got error 217 - 'Current transaction isolation level does not support this kind of flashback queries.' from storage engine

  • create table select 以及 insert into ... select... 仅在 READ COMMITTED 隔离级别下支持。在其他隔离级别下执行会报错 ERROR 1030 (HY000): Got error 217 - 'Current transaction isolation level does not support this kind of flashback queries.' from storage engine

  • 支持的闪回查询精度为秒级,不保证时间上百分之百准确;如果一秒之内有多个改动,可能会查询到其中任何一个。

  • 如果同一个闪回查询 statement 对一个表前后指定不同的时间戳,只能使用第一个时间戳,其余将被忽略。

  • 在执行 DDL 操作后,之前的数据不能进行闪回查询。若闪回查询DDL之前的数据,结果可能不符合预期。

  • 由于主节点和只读节点之间存在时间差,指定相同时间进行闪回查询,从主节点和只读节点获得的结果可能不一样。为解决这一不一致的问题,代理会将闪回查询的 SQL 只分发给主节点。

  • 推荐在单表场景中使用闪回查询。多表闪回查询会导致查询性能劣化,不推荐在复杂查询场景下使用闪回查询。如 JOIN、子查询。

  • 推荐使用主键来进行闪回查询,若使用二级索引来进行闪回查询则性能较差。

  • 目前闪回查询必须指定 timestamp 字符串,不支持函数。

  • 开启闪回查询后会延迟 Undo 日志清理,在配置的 loose_rds_flashback_query_window 时间窗口内,打开闪回查询功能会使得 Undo 表空间增长,并且数据库的查询及写入性能会有下降。不建议将 loose_rds_flashback_query_window 设置过大,建议根据业务流量情况来配置。

  • 闪回查询的支持范围可以通过执行 show status like '%flashback%' ,在状态变量 Innodb_flashback_query_start_timeInnodb_flashback_query_end_time 中查看。这些时间戳的时区与 MySQL system_time_zone 一致。

  • 关闭loose_rds_flashback_query以后再开启,将不能查询到开启 loose_rds_flashback_query 之前的历史信息。

前提条件

  • 已创建 MySQL 8.0 实例,且实例的内核小版本为 20250215 或更新版本。关于创建实例和查看实例内核小版本的相关信息,请参见创建实例

    说明

    如您的实例是在 2025 年 02 月 15 日之后创建,则自动使用 20250215 或更新的内核小版本。如您的实例是在 2025 年 02 月 15 日之前创建,则会使用 20250215 之前的内核小版本。此时,您可通过手动方式升级实例的内核小版本,详细信息,请参见手动升级实例内核小版本

  • 已将参数 loose_rds_flashback_query 的运行值设置为 ON。关于修改参数的详细信息,请参见修改参数

  • 按需设置参数 loose_rds_flashback_query_window 的运行值。

使用说明

闪回查询提供了全新的 AS OF 语法,完成前提条件后,即可使用 AS OF 语法查询指定时间的数据。 AS OF 语法如下:

SELECT column_name_list FROM table_name AS OF TIMESTAMP time_expr alias WHERE...;

语法中涉及的参数说明如下:

参数名称是否必选参数说明
column_name_list查询的列名。

table_name
table1_name
table2_name
table3_name

表名。

time_expr

  • 闪回的时间戳,为时间字符串,精确到秒。

  • 格式为:YYYY-MM-DD HH-MM-SS

  • 不支持在该参数中使用函数。

alias
alias1
alias2
alias3

表的别名。

join_cond1
join_cond2

JOIN条件。

使用示例

  • 查询指定时间参考

    mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> create table t1(id int,c1 int) engine=innodb;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> insert into t1 values(1,1),(2,2),(3,3),(4,4);
    Query OK, 4 rows affected (0.00 sec)
    Records: 4  Duplicates: 0  Warnings: 0
    
    mysql> select now();
    +---------------------+
    | now()               |
    +---------------------+
    | 2025-03-18 11:54:55 |
    +---------------------+
    1 row in set (0.00 sec)
    
    mysql> delete from t1 where id=4;
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t1;
    +------+------+
    | id   | c1   |
    +------+------+
    |    1 |    1 |
    |    2 |    2 |
    |    3 |    3 |
    +------+------+
    3 rows in set (0.00 sec)
    
    mysql> select * from t1 as of timestamp '2025-03-18 11:54:55';
    +------+------+
    | id   | c1   |
    +------+------+
    |    1 |    1 |
    |    2 |    2 |
    |    3 |    3 |
    |    4 |    4 |
    +------+------+
    4 rows in set (0.00 sec)
    
  • 通过历史数据创建表

    mysql> create table t3 select * from t1 as of timestamp '2025-03-18 11:54:55';
    Query OK, 4 rows affected (6.39 sec)
    Records: 4  Duplicates: 0  Warnings: 0
    
    mysql> select * from t3;
    +------+------+
    | id   | c1   |
    +------+------+
    |    1 |    1 |
    |    2 |    2 |
    |    3 |    3 |
    |    4 |    4 |
    +------+------+
    4 rows in set (0.00 sec)
    
  • 插入历史数据至表中

    mysql> create table t4 like t1;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> insert into t4 select * from t1 as of timestamp '2025-03-18 11:54:55';
    Query OK, 4 rows affected (0.09 sec)
    Records: 4  Duplicates: 0  Warnings: 0
    
    mysql> select * from t4;
    +------+------+
    | id   | c1   |
    +------+------+
    |    1 |    1 |
    |    2 |    2 |
    |    3 |    3 |
    |    4 |    4 |
    +------+------+
    4 rows in set (0.00 sec)