Oracle闪回技术(Flashback)

Oracle闪回技术(Flashback)
https://www.cnblogs.com/ivictor/p/3975339.html
闪回技术有闪回表、闪回删除、闪回查询、闪回事务查询、闪回事务、闪回数据库、闪回数据归档。其中,闪回查询、闪回事务查询用来“观察”过去;闪回数据归档并不是一个独立的功能,其功能是扩展闪回查询的时间窗口;闪回表、闪回删表能够以表为单位“回到”过去;闪回事务能够以事务为单位“回到”过去;闪回数据库能够以数据库为单位“回到”过去。

一、 闪回表(Flashback Table)

闪回表是利用UNDO表空间的撤销数据,所以能把表闪回到多久之前受到undo_retention,UNDO表空间的数据文件是否启动自动增长功能,是否设置guarantee等三种因素的影响。

附:scn 和时间的对应关系
查询当前scn
select current_scn from v$database;
select dbms_flashback.get_system_change_number scn from dual;
scn 转换成时间
select scn_to_timestamp(3525201) scn from dual;
时间转化成scn
select timestamp_to_scn(to_timestamp('2018-12-28 09.02.33.000000000','YYYY-MM-DD HH24:MI:SS.FF')) scn from dual; 
scn和时间的对应关系
select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') time from sys.smon_scn_time where rownum < 10 order by 1,2;
select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') time from sys.smon_scn_time where rownum < 10 order by 1 desc;


1、闪回到具体时间:
set time on;        --开启时间显示
select table_name,ROW_MOVEMENT from tabs;
alter table t6 enable row movement;    ----开启 t6 表的行级移动功能

insert into t6 values(1,'ZhangSan');
commit;        --注意,如果不 commit 就总只有第一条数据;

insert into t6 values(2,'LiSi');

select * from t6 as of timestamp to_timestamp('2018-12-28 09:36:22','yyyy-mm-dd hh24:mi:ss');     --ZhnagSan 的插入时间
select * from t6 as of timestamp to_timestamp('2018-12-28 09:36:28','yyyy-mm-dd hh24:mi:ss');     --LiSi 的插入时间
select * from t6 as of timestamp to_timestamp('2018-12-28 09:38:02','yyyy-mm-dd hh24:mi:ss');    --shutdown 的时间
select * from t6 as of timestamp to_timestamp('2018-12-28 09:42:14','yyyy-mm-dd hh24:mi:ss');    --重新启动open时的时间

insert into t6 values(3,'WangWu');    --插入 WangWu 的数据,但不commit
select * from t6 as of timestamp to_timestamp('2018-12-28 09:53:54','yyyy-mm-dd hh24:mi:ss');    --WangWu 的插入时间,此时是没有WangWu的信息的
select * from t6;        --这种方式可以查询到 WangWu的信息
--此时shutdown immediate 关闭数据库,并 startup,观察WangWu 的信息

select * from t6 as of timestamp to_timestamp('2018-12-28 09:57:59','yyyy-mm-dd hh24:mi:ss');    --shutdown 的时间
--在 shutdown 这个时间点就可以查询到 WangWu 的信息了,说明在一致性关库的时候,oracle 会做赃块的写入操作,也就是会做 commit 的动作

select * from t6 as of timestamp to_timestamp('2018-12-28 09:57:57','yyyy-mm-dd hh24:mi:ss');    --shudown 时间 返回 2 秒无法查询到 Wangwu 信息
--说明在 shudown 前 2 秒还没有执行 脏块写入

select * from t6 as of timestamp to_timestamp('2018-12-28 09:57:58','yyyy-mm-dd hh24:mi:ss');    --shudown 时间 返回 1 秒可以查询到 WangWu 信息
--说明在 shudown 前 1 秒会做数据的脏块写入

delete from t6;
select * from t6 as of timestamp to_timestamp('2018-12-28 10:05:14','yyyy-mm-dd hh24:mi:ss');    --delete from t6 的时间,可以查询到 t6 全部的数据信息

insert into t6 values(4,'ZhaoLiu');    --不执行 commit 动作
select * from t6 as of timestamp to_timestamp('2018-12-28 10:08:57','yyyy-mm-dd hh24:mi:ss');    --插入 ZhaoLiu 的时间


select * from t6;        --经过上面的操作,现在 t6 表只有一条 ZhaoLiu 的信息
flashback table t6 to timestamp to_timestamp('2018-12-28 09:36:28','yyyy-mm-dd hh24:mi:ss');    --闪回到 LiSi 数据的插入时间(闪回到具体时间)
select * from t6;        --此时查询就只有 ZhangSan  的数据了
--重点注意:因为 ZhaoLiu 的数据没有 commit,那么在闪回到 ZhangSan 的数据时,ZhaoLiu 的数据将完全丢失,切记,如果 ZhaoLiu 的数据是有效的,就恢复不回来了
--建议:在 执行闪回前,做个 shutdom immediate 的操作


flashback table t6 to timestamp(systimestamp-interval '60' minute);    --闪回到10分钟之前

select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') time from sys.smon_scn_time order by 1;    --查看 scn 和时间的对应关系
flashback table t6 to scn 3535928;    --闪回到scn 为 3535928 的时候
flashback table t6,t7 to scn 3535928;    --将 t6 和 t7 同时闪回到scn 为 3535928 的时候(主要用于有外键约束的表)

使用闪回表注意如下事项:

(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”的效果。
alter system set recyclebin='OFF' scope=spfile;    --禁用回收站功能
alter system set recyclebin='ON' scope=spfile;    --开启回收站功能
show parameter recyclebin    --查看功能是否开启

show recyclebin            ---查询恢复区被删除的信息
select * from recyclebin;    --查询恢复区被删除的信息

drop table t6;
flashback table t6 to before drop;    --闪回被删除的表

drop table t6;
create table t6 as select * from t;
flashback table t6 to before drop;    --表被删掉后,又新建了一个同名表,如果试图用上述命令闪回原表,则会报如下错误,可重新命名。
flashback table t6 to before drop
*
ERROR at line 1:
ORA-38312: original name is used by an existing object

flashback table t6 to before drop rename to t10;    --闪回重命名表

--闪回的遵循法则:
drop table t6;
create table t6 as select * from t;
drop table t6;
show recyclebin;    --此时在回收站中有 2 条 t6 记录
flashback table t6 to before drop;    --闪回 t6 表
show recyclebin;    --可以看到遵循的是后入先出,意思是说后进入回收站的,先闪回

drop table t6;
show recyclebin;
flashback table "BIN$fg/PSf3UtdHgU6wNAAq4fQ==$0" to before drop;    --指明被恢复的回收站对象

闪回删表的工作原理是:当“drop table”命令执行时,表及其索引并没有被真正删除,其所占空间只是分配给了另一个数据库对象:回收站对象,本质上相当于重命名。注意:表空间在自动增长的压力下会按照先入先出的规则将回收站对象的空间分配给需要空间的段,在将回收站对象耗尽之前数据文件是不会自动增长的。

purge recyclebin;    --删除回收站所有的对象


三、 闪回查询(Flashback Query)
以表为单位查询过去的数据称为闪回查询,主要有两种方式:1. 闪回时间点查询。利用select命令的“as of”子句与PL/SQL包dbms_flashback在过去的一个时间点上的查询。2. 闪回版本查询。利用select命令的“versions between”子句在过去的一段时间范围内的查询。
闪回时间点查询:利用“as of”子句

insert into t6 values(2,'LiSi');    --14:22:58 
commit;
insert into t6 values(3,'WangWu');    --14:25:07
commit;
insert into t6 values(4,'ZhaoLiu');    14:26:03
commit;

select * from t6 as of timestamp to_timestamp('2018-12-28 14:22:58','yyyy-mm-dd,hh24:mi:ss')     --查询某一时间点的数据    
select * from t6 as of timestamp (systimestamp - interval '5' minute) ;    --查询5 分钟前的数据
select * from t6 as of scn 3539196;    --查询具体在某个 scn 的时候的数据

利用dbms_flashback包
利用dbms_flashback包的enable_at_time或enable_at_scn存储过程锁定一个会话级别的闪回时间目标,即进入闪回模式,随后的查询命令可以省略“as of”,直到调用dbms_flashback_disable存储过程将其关闭为止。
比如,将闪回模式会话定格在24分钟前:    
select * from t6 as of timestamp (systimestamp - interval '24' minute);    --查询 24 分钟之前的数据
exec dbms_flashback.enable_at_time(systimestamp - interval '24' minute);    --启用闪回会话,将闪回模式会话锁定在 24 分钟之前
select * from t6;    --在闪回会话模式的时候,可以不需要 as of 子句
--此时若访问SYSDATE、SYSTIMESTAMP等日期函数,它们的返回值仍是当前值,而不是24分钟之前的值
drop table t6;    --在闪回会话模式,执行 ddl 和 dml 将报如下错误
drop table t6
*
ERROR at line 1:
ORA-08182: operation not supported while in Flashback mode
exec dbms_flashback.disable;        --结束闪回会话


exec dbms_flashback.enable_at_time(systimestamp - interval '24' minute);    --启用闪回会话
exec dbms_flashback.disable;        --结束闪回会话    


4、闪回版本查询
闪回版本查询可以贯穿一定长度的时间窗口,通过只使用一条查询命令就能返回该时间窗口内不同时间点上的数据。
如下示例:    

create table t11 as select id from t;    --15:02:25
select * from t11;
     1
update t11 set id = 11;        --15:03:16   
update t11 set id = 12;        --15:03:58
update t11 set id = 13;        --15:04:09
update t11 set id = 14;        --15:04:21
update t11 set id = 15;        --15:04:27  
commit;                --由于上面的 update 没有执行 commit,所以本句执行后,上面的数据将不会进入闪回区
update t11 set id = 16;        --15:07:42
commit;
update t11 set id = 17;        --15:08:32
commit;
update t11 set id = 18;        --15:08:54
commit;

select * from t11 versions between timestamp(systimestamp -interval '6' minute) and maxvalue;    --执行闪回版本查询

--通过“versions between”,我们可以看到在6分钟之内,t11 表的 id 列有 4 次更改。
--为了能看清这些事务的先后顺序,可以在查询列表中使用伪字段。如下所示:

select versions_xid,versions_startscn,versions_endscn,id from t11 versions between timestamp(systimestamp - interval '15' minute) and maxvalue order by 2 nulls first;

--ORA-01466    执行闪回操作,查询15 分钟之前的数据,报如下错误:说明 15 分钟前这个表是不存在的
select versions_xid,versions_startscn,versions_endscn,id from t11 versions between timestamp(systimestamp - interval '15' minute) and maxvalue;
select versions_xid,versions_startscn,versions_endscn,id from t11 versions between timestamp(systimestamp - interval '15' minute) and maxvalue
                                                              *
ERROR at line 1:
ORA-01466: unable to read data - table definition has changed

--其中:
-----versions_xid为事务号
-----versions_startscn和versions_endscn分别是事务开始时的SCN和修改该行的下一个事务开始时的SCN。
-----首尾衔接这两个字段的SCN号很容易得出真实的修改顺序

猜你喜欢

转载自blog.csdn.net/yaoshixian/article/details/85322564