#FLASHBACK

# 通用描述

FLASHBACK用于实现对表的历史数据闪回。

FLASHBACK的使用遵守如下规则:

  • 本语句仅适用于单机HEAP表。
  • FLASHBACK不允许使用于在以下闪回的SCN至当前期间内,发生过以下改变了表结构的DDL:
    • UPDATE TABLE、 MOVE TABLE、 TRUNCATE TABLE
    • 表增加约束
    • MODIFY COLUMN、 DROP COLUMN
    • ADD 、DROP、MERGE、SPLIT、COALESCE、TRUNCATE分区或子分区
  • FLASHBACK不允许在事务中进行
  • FLASHBACK的表不允许与其他表存在依赖关系
  • FLASHBACK不维护ROWID
  • FLASHBACK仅对当前时刻存在的索引进行维护,即使SCN点该索引还未创建;SCN点已存在的索引在当前时刻不存在时,不会恢复索引。
  • FLASHBACK不允许会违反约束的数据。
  • FLACKBACK适用于多表的场景下必须全部成功或全部失败。
  • FLACKBACK不还原统计信息。

# 语句定义

flashback::=

syntax
FLASHBACK TABLE table_name TO SCN scn Timestamp timestamp BEFORE DROP RENAME TO new_name TRUNCATE PARITITION part_name TO BEFORE TRUNCATE

# to scn|timestamp

该语句用于将表的数据闪回至指定的SCN|TIMESTAMP点,此功能无需开启回收站。

通过此功能闪回的数据可能会发生rowid的变化,因此执行前需要开启表的ROW MOVEMENT开关(参考ALTER TABLE中描述语法),否则将返回错误。

当需要闪回的表存在外键约束的情况下,需要在执行前先删除其他表中的外键约束,否则将返回错误。

示例

--area表中存在的一条记录
SELECT * FROM area WHERE area_no='03';
AREA_NO AREA_NAME         DHQ                  
------- ----------------- ---------------------
03      华南               Guangzhou           
 
--获取当前时间戳
SELECT TO_CHAR(SYSDATE,'yyyy/mm/dd hh24:mi:ss') TIME FROM dual;
TIME
----------------------------------------------------------------
2024/03/29 14:47:33

--获取当前SCN(通过CURRENT_SCN获取)
SELECT CURRENT_SCN FROM V$DATABASE;
          CURRENT_SCN 
--------------------- 
   408883147271815168        
        
--获取最后一次修改时SCN(通过ROWSCN获取)
SELECT rowscn FROM area WHERE area_no='03';
               ROWSCN 
--------------------- 
   408883147271815168

--删除此条记录并提交
DELETE FROM area WHERE area_no='03';
COMMIT;
SELECT * FROM area WHERE area_no='03';
AREA_NO AREA_NAME  DHQ                  
------- ---------- ---------------------
 
 
--利用FLASHBACK闪回历史数据(通过时间戳闪回)
FLASHBACK TABLE area TO TIMESTAMP TO_TIMESTAMP('2023/03/01 01:11:50','yyyy/mm/dd hh24:mi:ss');
AREA_NO AREA_NAME         DHQ                  
------- ----------------- ---------------------
03      华南               Guangzhou   
 
--利用FLASHBACK闪回历史数据(通过SCN闪回)
FLASHBACK TABLE area TO SCN 408883147271815168;

# before

该语句用于将被删除的表闪回至删表之前的状态,或者将被truncate的表的数据闪回,此功能需要开启回收站(修改配置参数RECYCLEBIN_ENABLED为ON)。

# drop

该语句用于将被删除的表闪回,包括表结构和数据。

实际情况中,被删除的表名称有可能已经被重建,或被其他对象占用,此时需指定RENAME TO关键字用于为恢复的表重命名,否则将报YAS-02013错误。

示例

DROP TABLE finance_info;

SELECT * FROM finance_info;
[1:15]YAS-02012 table or view does not exist

FLASHBACK TABLE finance_info TO BEFORE DROP;
--当finance_info名称已被使用时,需对其重命名
--FLASHBACK TABLE finance_info TO BEFORE DROP RENAME TO finance_info_new;

SELECT * FROM finance_info;
YEAR  MONTH BRANCH REVENUE_TOTAL  COST_TOTAL   FEE_TOTAL 
----- ----- ------ ------------- ----------- ----------- 
2001  01    0201            2888        2000         300
2021  01    0201           28888       24000        3000
2021  01    0101           38888       34000        4000
2021  02    0101           37778       33000        6000

# truncate

该语句用于将表truncate的数据闪回。

示例

TRUNCATE TABLE sales_info_range;

SELECT * FROM sales_info_range;
YEAR  MONTH BRANCH PRODUCT      QUANTITY      AMOUNT SALSPERSON    
----- ----- ------ --------- ----------- ----------- ------------- 

FLASHBACK TABLE sales_info_range TO BEFORE TRUNCATE;

SELECT * FROM sales_info_range;
YEAR  MONTH BRANCH PRODUCT      QUANTITY      AMOUNT SALSPERSON    
----- ----- ------ --------- ----------- ----------- ------------- 
2001  01    0201   11001              30         500 0201010011   
2000  12    0102   11001              20         300              
2015  11    0101   11001              20         300              
2015  03    0102   11001              20         300              
2021  10    0101   11001              20         300              
2021  05    0101   11001              40         600  

# partition

对于某个分区的truncate,本语句支持对该分区的数据闪回,此功能需要开启回收站(修改配置参数RECYCLEBIN_ENABLED为ON)。

实际情况中,某个分区或子分区被truncate后可能会新插入数据,此时执行闪回将导致这部分数据被truncate到回收站中。同时若有存在该表被外键依赖的全局索引主键或唯一键则会报错。

示例(HEAP表)

ALTER TABLE sales_info_list TRUNCATE PARTITION p_sales_info_list_2;

SELECT * FROM sales_info_list PARTITION (p_sales_info_list_2);
YEAR  MONTH BRANCH PRODUCT      QUANTITY      AMOUNT SALSPERSON    
----- ----- ------ --------- ----------- ----------- ------------- 

INSERT INTO sales_info_list VALUES ('2021','06','0101','11001',40,600,'');
COMMIT;

FLASHBACK TABLE sales_info_list PARTITION p_sales_info_list_2 TO BEFORE TRUNCATE;

--闪回后上面新增的数据被放入回收站,p_sales_info_list_2分区中只存在回收站上一次的数据
SELECT * FROM sales_info_list PARTITION (p_sales_info_list_2);
YEAR  MONTH BRANCH PRODUCT      QUANTITY      AMOUNT SALSPERSON    
----- ----- ------ --------- ----------- ----------- ------------- 
2021  05    0101   11001              40         600