【引言】
闪回技术有闪回表、闪回删除、闪回查询、闪回事务查询、闪回事务、闪回数据库、闪回数据归档。
其中,闪回查询、闪回事务查询用来“观察”过去;闪回数据归档并不是一个独立的功能,其功能是扩展闪回查询的时间窗口;闪回表、闪回删表能够以表为单位“回到”过去;闪回事务能够以事务为单位“回到”过去;闪回数据库能够以数据库为单位“回到”过去。
闪回技术都包含7种技术:
1.flashback query
2.flashback data archive
3.flashback transaction query
4.flashback version
5.flashback table
6.flashback drop
7.flashback database
一、 闪回查询(Flashback Query)
以表为单位查询过去的数据称为闪回查询,主要有两种方式:1. 闪回时间点查询。利用select命令的“as of”子句与PL/SQL包dbms_flashback在过去的一个时间点上的查询。2. 闪回版本查询。利用select命令的“versions between”子句在过去的一段时间范围内的查询。
1.1 闪回时间点查询,利用“as of”子句
-
查询12306号员工在具体时间的工资
SQL> select sal from emp as of timestamp to_timestamp(‘2020-10-29 10:02:30’,‘yyyy-mm-dd,hh24:mi:ss’) where empno=12306; -
查询12306号员工在五分钟前的工资
SQL> select sal from emp as of timestamp (systimestamp - interval ‘5’ minute) where empno=12306; -
查询具体SCN
SQL> select * from emp as of scn 1095000; -
将12306号员工的工资修改为15分钟之前的值
SQL> update emp set sal=(select sal from emp as of timestamp(systimestamp - interval ‘15’ minute) where empno=7888) where empno=12306;
利用dbms_flashback包
利用dbms_flashback包的enable_at_time或enable_at_scn存储过程锁定一个会话级别的闪回时间目标,即进入闪回模式,随后的查询命令可以省略“as of”,直到调用dbms_flashback_disable存储过程将其关闭为止。
比如,将闪回模式会话定格在15分钟前:
SQL> exec dbms_flashback.enable_at_time(systimestamp - interval ‘15’ minute);
注意:此时查询的是15分钟之前的表。
SQL> select sal from emp where empno=12306; --忽略了“as of”子句
此时若访问SYSDATE、SYSTIMESTAMP等日期函数,它们的返回值仍是当前值,而不是15分钟之前的值。
处于闪回会话模式时,执行dml和ddl将报错
SQL> update emp set sal=4000 where empno=12306;
update emp set sal=4000 where empno=12306
*
ERROR at line 1:
ORA-08182: operation not supported while in Flashback mode
如果查询完毕,可调用disable存储过程关闭闪回会话模式。
SQL> exec dbms_flashback.disable;
1.2 闪回版本查询
闪回版本查询可以贯穿一定长度的时间窗口,通过只使用一条查询命令就能返回该时间窗口内不同时间点上的数据。
比如,首先通过3个事务将12306号员工的工资进行修改。其值原来是4000,然后是5000,然后是10000,最后是3000.
SQL> select sal from emp where empno=12306;
SAL----------
4000
SQL> update emp set sal=5000 where empno=12306;
1 row updated.
SQL> commit;
Commit complete.
SQL> update emp set sal=10000 where empno=12306;
1 row updated.
SQL> commit;
Commit complete.
SQL> update emp set sal=3000 where empno=12306;
1 row updated.
SQL> commit;
Commit complete.
执行闪回版本查询
SQL> select empno,sal from emp
2 versions between timestamp(systimestamp -interval ‘15’ minute) and maxvalue
3 where empno=12306;
EMPNO SAL----- ----------
12306 3000
12306 10000
12306 5000
12306 4000
通过“versions between”,我们可以看到在15分钟之内,12306号员工的工资用4个值,说明共有3个事务对其进行过修改。为了能看清这些事务的先后顺序,可以在查询列表中使用伪字段。
如下所示:
SQL> select
2 versions_xid,versions_startscn,versions_endscn,
3 empno,sal
4 from emp
5 versions between timestamp(systimestamp - interval ‘15’ minute) and maxvalue
6 where empno=12306
7 order by 2 nulls first;
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN EMPNO SAL
060002000F030000 1097139 12306 4000
02001100FB020000 1097139 1097148 12306 5000
03001D001E030000 1097148 1097153 12306 100000900170000030000 1097153 12306 3000
其中,versions_xid为事务号versions_startscn和versions_endscn分别是事务开始时的SCN和修改该行的下一个事务开始时的SCN。首尾衔接这两个字段的SCN号很容易得出真实的修改顺序:4000,5000,10000,最后是3000.
二、flashback data archive
flashback data archive【将原本只能保存在undo中的撤销数据保存在普通表空间中,这样可以查询表很长时间以前的旧数据】
如何对表创建flashback data archive。
SQL> create flashback archive default fda_default tablespace fda_tbs retention 1 year;
Flashback archive created.
SQL> grant flashback archive on fda_default to ethanDB;
Grant succeeded.
SQL> alter table ethanDB.fda_test flashback archive;
Table altered.
SQL> select count(*) from ethanDB.fda_test as of timestamp (systimestamp -interval ‘7’ month); *
ERROR at line 1:
ORA-08180: no snapshot found based on specified time
SQL> select count(*) from ethanDB.fda_test as of timestamp (systimestamp -interval ‘1’ day);
在fda中,创建的flashback data archive是如何存储的?
SEGMENT_NAME SEGMENT_TYPE
--------------------------------------------------------------------------------- ------------------
FDA_TEST TABLE
SYS_FBA_DDL_COLMAP_73240 TABLE
SYS_FBA_TCRV_73240 TABLE
SYS_FBA_HIST_73240 TABLE PARTITION --这个表存放的就是fda_test的历史数据
SYS_FBA_TCRV_IDX_73240 INDEX
开启flashback data archive的表如果有不被允许的ddl报错
SQL> alter table ethanDB.fda_test shrink space;alter table ethanDB.fda_test shrink space*
ERROR at line 1:
ORA-55610: Invalid DDL statement on history-tracked table
哪些ddl可以在开启历史表的的表上操作?
1、对字段的add、drop、rename、modify修改2、对约束的add、drop、rename修改3、对分区的drop、truncate操作4、对表的truncate和rename操作
三、flashback transaction query
一定需要开启最小补充日志;查询返回的结果是将当前数据修改为以前数据的撤销sql。
SQL> alter database add supplemental log data; --这个比较关键
Database altered.
SQL> select SUPPLEMENTAL_LOG_DATA_MIN from v$database;
SUPPLEMENTAL_LOG_DATA_MI------------------------
YES
基于事务的查询:
SYS> select xid, operation, commit_scn, undo_sql
2 from flashback_transaction_query where xid in (
3 select versions_xid from hr.regions
4 versions between scn minvalue and maxvalue);
或者
select distinct xid,commit_scnfrom flashback_transaction_querywhere table_name='REGIONS’and table_owner='HR’and commit_timestamp > systimestamp - interval ‘10’ minute order by commit_scn;
四、flashback version
基于版本的查询:
SYS> select versions_xid, versions_startscn, versions_endscn,
decode(versions_operation,‘I’,‘Insert’,‘U’,‘Update’,‘D’,‘Delete’,‘Original’
“Operation” from hr.regions versions between scn minvalue and maxvalue;
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN Operatio
0300200066030000 1112617 Update
0300200066030000 1112617 Update
0800200033030000 1112614 Update
0800200033030000 1112614 Update
0800200033030000 1112614 1112617 Update
07000F003E030000 1112137 1112614 Insert
07000F003E030000 1112137 1112614 Insert
07000F003E030000 1112137 1112614 Insert
07000F003E030000 1112137 1112617 Insert
07000F003E030000 1112137 Insert
SYS> flashback table hr.regions to scn 1112137;
Flashback complete.
五、 闪回表(Flashback Table)
闪回表是利用UNDO表空间的撤销数据,把表闪回到某个时间点或者scn,受到undo_retention,UNDO表空间的数据文件是否启动自动增长功能,是否设置guarantee等三种因素的影响。
- 闪回到具体时间
先查看之前的内容
select * from scott.emp as of timestamp to_timestamp(‘2020-10-16 04:32:00’,‘yyyy-mm-dd hh24:mi:ss’) where object_id=100;
在闪回上述确定的时间点信息
SQL> flashback table scott.emp to timestamp to_timestamp(‘2014-09-16 04:32:00’,‘yyyy-mm-dd hh24:mi:ss’);
-
闪回到10分钟之前
SQL> flashback table scott.emp to timestamp(systimestamp-interval ‘10’ minute); -
将scott.emp闪回到SCN为1086000的时候
SQL> flashback table scott.emp to scn 1086000; -
将scott.emp和scott.dept两张表同时闪回到SCN为108611的时候(主要用于有外键约束的表)
SQL> flashback table scott.emp,scott.dept to scn 108611;
使用闪回表注意如下事项:
(1)被闪回的表必须启用行移动功能
SQL> alter table dept enable row movement;
(2)“FLASHBACK TABLE”命令的执行者必须有“FLASHBACK ANY TABLE”系统权限或者在被闪回的表上具有“FLASHBACK”对象权限。
(3)“FLASHBACK TABLE”属于DDL命令,隐式提交。
(4)SYS用户的任何表无法使用此功能。
六、 闪回删表(Flashback Drop)
闪回删表的目的是撤销“DROP TABLE”的效果。
-
闪回被删掉的scott.emp表
SQL> flashback table scott.emp to before drop; -
表被删掉后,又新建了一个同名表,如果试图用上述命令闪回原表,则会报ORA-38312: original name is used by an existing object错误,可重新命名。
SQL> flashback table test to before drop rename to test1;
3.如果表名重复,则闪回时遵循后入先出的原则。
-
闪回时可指明被恢复的回收站对象
SQL> flashback table “BIN$AyId7ZbBjWngUKjADQIIuA==$0” to before drop;
闪回删表的工作原理是:当“drop table”命令执行时,表及其索引并没有被真正删除,其所占空间只是分配给了另一个数据库对象:回收站对象,本质上相当于重命名。注意:表空间在自动增长的压力下会按照先入先出的规则将回收站对象的空间分配给需要空间的段,在将回收站对象耗尽之前数据文件是不会自动增长的。 -
可禁用回收站功能
SQL> alter system set recyclebin=‘OFF’ scope=spfile; -
删除当前用户回收站的所有对象
SQL> purge recyclebin;
七、flashback database必须要开启闪回日志。
查看是否开启flashback database功能
SYS> select oldest_flashback_scn,oldest_flashback_time from v$flashback_database_log;
如何开启?
SYS> alter system set db_recovery_file_dest_size=2014G;
System altered.
SYS> alter system set db_recovery_file_dest=’/home/oracle/flash’ scope=spfile;
System altered.
SYS> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SYS> startup mount;
ORACLE instance started.
Total System Global Area 941600768 bytes
Fixed Size 1348860 bytes
Variable Size 541068036 bytes
Database Buffers 394264576 bytes
Redo Buffers 4919296 bytes
Database mounted.
SYS> archive log list;
Database log mode No Archive Mode
Automatic archival Disabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 21
Current log sequence 23
SYS> alter database flashback on;
Database altered.
SYS> alter database open;
Database altered.
SYS> show parameter recovery
NAME TYPE VALUE
db_recovery_file_dest string +FRA
db_recovery_file_dest_size big integer 1000000M
recovery_parallelism integer 0
SQL> alter session set nls_date_format=‘yyyy-mm-dd hh24:mi:ss’;
Session altered.
SQL> select oldest_flashback_scn,oldest_flashback_time from v$flashback_database_log;
OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_TI-------------------- -------------------
803578 2020-10-26 18:08:28
执行truncate table, drop table等操作;
执行flashback database操作
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount exclusive;
ORACLE instance started.
Total System Global Area 941600768 bytes
Fixed Size 1348860 bytes
Variable Size 541068036 bytes
Database Buffers 394264576 bytes
Redo Buffers 4919296 bytes
Database mounted.
SQL> flashback database to timestamp(to_date(‘2020-10-26 18:08:28’,‘yyyy-mm-dd hh24:mi:ss’));
Flashback complete.
SQL> alter database open resetlogs;
Database altered.
在此过程中,主要使用了flashback log
欢迎关注个人微信公众号“一森咖记”