SELECT: FLASHBACK¶
说明¶
按照实现方式主要分为:基于回滚段进行闪回查询和基于归档日志进行闪回查询
- 基于回滚段进行闪回查询:使用回滚段的数据构造所需的数据
- 基于归档日志进行闪回查询:逆向扫描归档日志,构造出历史版本数据或者指定版本的数据
按照闪回功能主要分为:闪回版本查询和闪回时间点查询
- 闪回版本查询:根据归档/undo日志的数据模拟回滚操作构造出表中历史数据的版本
- 闪回时间点查询:根据undo日志的数据构造出指定版本的数据
参数¶
expr
当选择 TIMESTAMP 参数时,expr 对应的为时间戳; 当选择 SCN 参数时,expr 对应的为SCN的数值或表达式。
version_between
闪回版本查询,查询表中从BETWEEN指定的SCN/TIMESTAMP到AND指定的SCN/TIMESTAMP之间的所有数据版本,当指定的SCN范围为[MINVALUE-MAXVALUE]会构造出这个表自创建以来的所有数据版本。
as_of
闪回时间点查询,根据AS OF指定的SCN/TIMESTAMP构造出对应时间点的数据。
相关配置参数:¶
- ENABLE_FLASHBACK_QUERY_USE_ARCHIVELOG(默认为FALSE):是否基于归档日志进行闪回查询。
- ENABLE_FLASHBACK_QUERY_LOB_AS_NULL(默认为FALSE):是否在闪回查询中将大对象直接返回为NULL,当设置为FALSE时遇到大对象或用到大对象的text,xml类型会报错。
- FLASHBACK_MEM(默认 1GB):在基于归档日志进行闪回查询时最多可以使用多大的内存空间。
方式对比:¶
- 基于回滚段进行闪回时间点查询可以充分利用现有的多版本机制,性能较好,缺点是受限于回滚段重用机制,只能查询很短时间之内的数据。神通数据库目前基于回滚段的闪回查询只支持闪回时间点查询。
- 基于归档日志方式进行闪回查询的好处是只要有归档日志,可以查询很长时间之内的数据,缺点是性能较差,并且需要占用内存和临时表空间(要查询的版本越旧,需要的内存和临时表空间越多)。
相关伪列:¶
符号 说明 VERSIONS_STARTSCN 本历史行的生成SCN VERSIONS_ENDSCN 本历史行的消失SCN VERSIONS_STARTTIME 本历史行的生成时间 VERSIONS_ENDTIME 本历史行的消失时间 VERSIONS_XID 本历史行的操作事务号 VERSIONS_OPERATION 生成本历史行的操作
注解
特别说明:
- 闪回查询可能会遇到“快照过旧,当前索引有过空页面清理操作,因此无法处理清理操作之前索引相关的事务”这种报错。
原因是:神通数据库支持自动清理索引空页面,并且无法再恢复这些页面的历史版本,闪回查询无法对这些页面的修改进行进行回滚
解决方法:避免闪回查询走索引扫描。例如指定 hint。
- 基于归档日志的闪回查询,可能会遇到“闪回查询构造快照页面失败”这种报错。
原因是:从要闪回的时间点到当前时刻,已产生的日志量越大,闪回时需要逆向扫描的日志就越多,这个时间如果超过了数据库配置参数 UNDO_RETENTION 的值,可能导致上述报错。
解决方法:通过 SET 命令,将参数 UNDO_RETENTION 的值修改成比报错语句的执行时间更大的值,重新进行闪回查询。并在查询成功后,再将参数值改回为原来的值。
示例¶
示例1: 按照时间点进行闪回查询
-- 清理环境
DROP TABLE tab1 CASCADE;
-- 创建表
CREATE TABLE tab1 (a INT, b INT);
-- 查看当前时间
SELECT TO_CHAR(SYSDATE,'yyyy-mm-dd hh24:mi:ss') FROM DUAL;
TO_CHAR
---------------------
2019-11-29 15:59:28
(1 row)
-- 插入数据
INSERT INTO tab1 VALUES(1, 10);
INSERT INTO tab1 VALUES(2, 20);
-- 查看当前时间
SELECT TO_CHAR(SYSDATE,'yyyy-mm-dd hh24:mi:ss') FROM DUAL;
TO_CHAR
---------------------
2019-11-29 16:01:36
(1 row)
-- 普通查询
SELECT * FROM tab1;
A | B
---+----
1 | 10
2 | 20
(2 rows)
-- 按时间点闪回查询
SELECT * FROM tab1 AS OF TIMESTAMP '2019-11-29 15:59:28';
A | B
---+---
(0 rows)
SELECT * FROM tab1 AS OF TIMESTAMP '2019-11-29 16:01:36';
A | B
---+----
1 | 10
2 | 20
(2 rows)
-- 查询一段时间内的操作记录
SELECT VERSIONS_STARTSCN, VERSIONS_ENDSCN, VERSIONS_STARTTIME, VERSIONS_ENDTIME, VERSIONS_XID::BINARY(8)::INT8, VERSIONS_OPERATION, ROWID, * FROM tab1 VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE;
VERSIONS_STARTSCN | VERSIONS_ENDSCN | VERSIONS_STARTTIME | VERSIONS_ENDTIME | VERSIONS_XID | VERSIONS_OPERATION | ROWID | A | B
-------------------+-----------------+---------------------+------------------+-------------------+--------------------+-----------------+---+----
3305 | | 2019-11-29 16:01:10 | | 32369678156300289 | I | 17698 | 1 | 10
3306 | | 2019-11-29 16:01:10 | | 32369682451267585 | I | 281474976728354 | 2 | 20
(2 rows)
-- 删除表
DROP TABLE tab1;