本篇主要介绍OceanBase的Oracle模式下的闪回查询示例和使用限制。
本系列总的专栏:一步一步学习OceanBase系列
闪回查询(Flashback Query)是 Oracle 中记录级别的闪回功能。该功能允许用户获取某个历史版本的数据,OceanBase当前仅支持 Oracle 模式下的闪回查询。
闪回查询支持 SCN(System Change Number)和 TIMESTAMP 两种维度的查询。
示例:
闪回查询的使用示例如下:1、通过 TIMESTAMP 指定的历史时间并闪回查询一张单表在该历史时间中的状态的数据。
obclient> SELECT * FROM tbl1 AS of timestamp to_timestamp('2020-08-13 16:20:00','yyyy-mm-dd hh24:mi:ss');
2、通过 TIMESTAMP 指定的历史时间并闪回查询多表在该历史时间中的状态的数据。
obclient> SELECT * FROM tbl1 AS of timestamp expr1,tbl2 AS of timestamp to_timestamp('2020-08-13 16:20:00','yyyy-mm-dd hh24:mi:ss');
3、通过 SCN 指定历史时间并闪回查询单表在该历史时间点的状态的数据。
obclient> SELECT * FROM tbl1 AS of scn 1582807800000000;
限制:
闪回查询的使用限制如下:
最近一小段时间受限制与 undo_retention变量设置有关,该参数默认为 0,默认单位为秒。假如 t1 时间点设置为了保留时间,且 t2 = t1 + 900s,那么 t2 时间点可以查询 [t1,t2] 区间内的数据,设置后对之前的数据不起作用,对之后的数据才起作用。
以下语句展示了如何设置undo_retention变量:
obclient> SET GLOBAL undo_retention=900;
OceanBase 数据库目前获取 SCN 号还没有完善的办法,故推荐使用 TIMESTAMP 来指定时间,这种方法与 Oracle 完全兼容。
通过查询固定时间点可以查询最近的一次合并版本。如果您在 t1 时间点发起了集群合并,您最早可以查询到 t1 时间点的数据。
如果被查询的表已经被删除进了回收站,那么需要先将该表从回收站中恢复。
闪回查询受限于转储,如果发生转储,且 undo_retention变量未设置,则无法查询。设置 undo_retention变量后可以查询 t1(转储时间点)+undo_retention变量设置的时间范围。
以下是关于ob闪回的测试:
obclient> --合并前表的数据情况obclient> select * from test;+----+----------------+------+---------------------+| ID | NAME | AGE | DT |+----+----------------+------+---------------------+| 2 | 张三 | 26 | 1998-06-17 00:00:00 || 3 | 李四 | 32 | 1989-10-13 00:00:00 || 4 | test-flashback | 20 | 2021-01-28 17:24:51 |+----+----------------+------+---------------------+3 rows in set (0.00 sec)obclient> --合并前的系统时间obclient> select sysdate from dual;+---------------------+| SYSDATE |+---------------------+| 2021-01-28 17:25:43 |+---------------------+1 row in set (0.00 sec)obclient> obclient> --开始做个合并 major freeze ;Query OK, 0 rows affected (0.00 sec)obclient> --合并完后查看系统时间obclient> select sysdate from dual;+---------------------+| SYSDATE |+---------------------+| 2021-01-28 17:35:19 |+---------------------+1 row in set (0.00 sec)obclient> select * from test;+----+----------------+------+---------------------+| ID | NAME | AGE | DT |+----+----------------+------+---------------------+| 2 | 张三 | 26 | 1998-06-17 00:00:00 || 3 | 李四 | 32 | 1989-10-13 00:00:00 || 4 | test-flashback | 20 | 2021-01-28 17:24:51 |+----+----------------+------+---------------------+3 rows in set (0.03 sec)obclient> obclient> --合并完成后,插入一笔数据obclient> insert into test values(5,'merge alter',20,sysdate);Query OK, 1 row affected (0.00 sec)obclient> commit;Query OK, 0 rows affected (0.00 sec)obclient> obclient> select * from test;+----+----------------+------+---------------------+| ID | NAME | AGE | DT |+----+----------------+------+---------------------+| 2 | 张三 | 26 | 1998-06-17 00:00:00 || 3 | 李四 | 32 | 1989-10-13 00:00:00 || 4 | test-flashback | 20 | 2021-01-28 17:24:51 || 5 | merge alter | 20 | 2021-01-28 17:36:22 |+----+----------------+------+---------------------+4 rows in set (0.01 sec)obclient> obclient> --可以闪回到最近一次合并的时间点obclient> select * from test as of timestamp to_timestamp('2021-01-28 17:35:19','yyyy-mm-dd hh24:mi:ss');+----+----------------+------+---------------------+| ID | NAME | AGE | DT |+----+----------------+------+---------------------+| 2 | 张三 | 26 | 1998-06-17 00:00:00 || 3 | 李四 | 32 | 1989-10-13 00:00:00 || 4 | test-flashback | 20 | 2021-01-28 17:24:51 |+----+----------------+------+---------------------+3 rows in set (0.00 sec)obclient> --无法闪回到最近一次合并之前的时间点,报错无效的闪回时间obclient> select * from test as of timestamp to_timestamp('2021-01-28 17:25:43','yyyy-mm-dd hh24:mi:ss');ORA-08186: invalid timestampobclient> obclient> obclient> --接下来测试下从回收站中闪回是否受合并影响obclient> show variables like 'recyclebin';+---------------+-------+| VARIABLE_NAME | VALUE |+---------------+-------+| recyclebin | ON |+---------------+-------+1 row in set (0.01 sec)obclient> select * from test;+----+---------------------+------+---------------------+| ID | NAME | AGE | DT |+----+---------------------+------+---------------------+| 5 | truncatebeforemajor | 22 | 2021-01-28 17:47:37 || 6 | aftermajor | 23 | 2021-01-28 17:57:48 |+----+---------------------+------+---------------------+2 rows in set (0.00 sec)obclient> --drop table 前的系统时间;obclient> select sysdate from dual;+---------------------+| SYSDATE |+---------------------+| 2021-01-28 18:06:23 |+---------------------+1 row in set (0.00 sec)obclient> obclient> --删除表obclient> drop table test;Query OK, 0 rows affected (0.21 sec)obclient> --drop table 后的系统时间;obclient> select sysdate from dual;+---------------------+| SYSDATE |+---------------------+| 2021-01-28 18:06:37 |+---------------------+1 row in set (0.00 sec)obclient>obclient> --执行一次合并;Query OK, 0 rows affected (0.00 sec)obclient> --合并后查看系统时间;obclient> select sysdate from dual;+---------------------+| SYSDATE |+---------------------+| 2021-01-28 18:18:19 |+---------------------+1 row in set (0.00 sec)obclient> select * from test;ORA-00942: table or view 'APS2.TEST' does not existobclient> obclient> --如果被闪回查询的表已经被删除进了回收站,那么需要先将该表从回收站中恢复。obclient> select * from test as of timestamp to_timestamp('2021-01-28 18:18:19','yyyy-mm-dd hh24:mi:ss');ORA-00942: table or view 'APS2.TEST' does not existobclient> obclient> --闪回被删除的表obclient> flashback table test to before drop;Query OK, 0 rows affected (0.20 sec)obclient> select * from test;+----+---------------------+------+---------------------+| ID | NAME | AGE | DT |+----+---------------------+------+---------------------+| 5 | truncatebeforemajor | 22 | 2021-01-28 17:47:37 || 6 | aftermajor | 23 | 2021-01-28 17:57:48 |+----+---------------------+------+---------------------+2 rows in set (0.00 sec)obclient> --表从回收站恢复后,闪回查询就可以进行,牛逼的是这个时间点其实是表还没恢复的时间点obclient> select * from test as of timestamp to_timestamp('2021-01-28 18:18:19','yyyy-mm-dd hh24:mi:ss');+----+---------------------+------+---------------------+| ID | NAME | AGE | DT |+----+---------------------+------+---------------------+| 5 | truncatebeforemajor | 22 | 2021-01-28 17:47:37 || 6 | aftermajor | 23 | 2021-01-28 17:57:48 |+----+---------------------+------+---------------------+2 rows in set (0.00 sec)obclient> --无法闪回到最近一次合并之前的时间点obclient> select * from test as of timestamp to_timestamp('2021-01-28 18:06:23','yyyy-mm-dd hh24:mi:ss');ORA-08186: invalid timestampobclient> select * from test as of timestamp to_timestamp('2021-01-28 18:06:37','yyyy-mm-dd hh24:mi:ss');ORA-08186: invalid timestampobclient> 一步一步学习oceanbase系列