Flashback table 闪表
回收站功能---> 将表改名而已 alter table Z1 rename to ZZ1;
回收站(recyclebin),是一个虚拟的容器,依旧在表的原表空间内,用于存放所有被删除的对象的数据字典
特点:
在线操作
自动恢复相关属性,如索引、触发器等
满足数据一致性,所有相关对象将自动一致
新数据空间需求不足 系统自动清理回收站
只能闪drop 不能闪truncate
闪回表有2中:
1、闪回整个删除的表 --基于undo表空间有数据库情况下 测试如果将undo表空间offline ,drop table T1, flashback table T1 to before drop;是成功的,后期查询是不行的,也就证明了“闪回查询是undo,而闪回表是回收站,闪回数据库则要依赖闪回区” recover datafile 4,alter database datafile 'E:\APP\ADMINISTRATOR\ORADATA\ORACLE11G\USERS01.DBF' online; SELECT FILE#, STATUS,RECOVER, NAME,error FROM V$DATAFILE_HEADER;数据文件的状态
2、闪回部分的DML操作的表 --要基于undo表空间里的内容,只要undo内容足够就可以反复flashback ,恢复某个时间点和scn号
测试1: --->整个表被删除的恢复, 数据文件空间(auto/nonauto)情况下,recyclebin变动情况
SCOTT@ora10g> drop table t4;
Table dropped.
SCOTT@ora10g> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
DEPT TABLE
EMP TABLE
BONUS TABLE
SALGRADE TABLE
T5 TABLE
T3 TABLE
T2 TABLE
BIN$mKoYM02QCojgQAB/AQAvyw==$0 TABLE
8 rows selected.
SCOTT@ora10g> 不放入回收站 直接删除
SCOTT@ora10g> drop table t3 purge;
Table dropped.
SCOTT@ora10g>
从回收站中恢复表
SCOTT@ora10g> show recycl
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T4 BIN$mKoYM02QCojgQAB/AQAvyw==$0 TABLE 2010-12-31:07:32:09
SCOTT@ora10g> flashback table t4 to before drop;
Flashback complete.
SCOTT@ora10g> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
DEPT TABLE
EMP TABLE
BONUS TABLE
SALGRADE TABLE
T5 TABLE
T4 TABLE
T2 TABLE
7 rows selected.
SCOTT@ora10g>
多次删除同一个表的恢复
SCOTT@ora10g> flashback table "BIN$mKoYM02RCojgQAB/AQAvyw==$0" to before drop;
Flashback complete.
SCOTT@ora10g>
SCOTT@ora10g> flashback table t4 to before drop rename to t7;
Flashback complete.
SCOTT@ora10g>
清空回收站
SCOTT@ora10g> sho recycle;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T4 BIN$mKoYM02UCojgQAB/AQAvyw==$0 TABLE 2010-12-31:08:35:06
SCOTT@ora10g> purge table t4;
Table purged.
SCOTT@ora10g> sho recycle;
SCOTT@ora10g> purge recyclebin;
带索引的表的闪回时 索引名称不会还原 要手动改
SQL> SELECT INDEX_NAME,TABLE_NAME FROM DBA_INDEXES WHERE TABLE_NAME='T2';
INDEX_NAME TABLE_NAME
------------------------------ ------------------------------
IND_T2 T2
SQL> drop table t2;
Table dropped.
SQL> select object_name,original_name,type from recyclebin;
OBJECT_NAME ORIGINAL_NAME TYPE
------------------------------ -------------------------------- -------------------------
BIN$nTKLacW7QjzgQAoKCgoJog==$0 IND_T2 INDEX
BIN$nTKLacW8QjzgQAoKCgoJog==$0 T2 TABLE
SQL> flashback table t2 to before drop;
Flashback complete.
SQL> SELECT INDEX_NAME,TABLE_NAME FROM DBA_INDEXES WHERE TABLE_NAME='T2';
INDEX_NAME TABLE_NAME
------------------------------ ------------------------------
BIN$nTKLacW7QjzgQAoKCgoJog==$0 T2
SQL> ALTER INDEX "BIN$nTKLacW7QjzgQAoKCgoJog==$0" RENAME TO "IND_T2";
Index altered.
SQL> SELECT INDEX_NAME,TABLE_NAME FROM DBA_INDEXES WHERE TABLE_NAME='T2';
INDEX_NAME TABLE_NAME
------------------------------ ------------------------------
IND_T2 T2
SQL>
当新数据增长 表空间容量不足时 回收站的内容会自动被系统清理
SQL> create tablespace mytbs datafile '/u01/oracle/oradata/ora10g/mytbs01.dbf' size 2M;
Tablespace created.
SQL> create table t1 tablespace mytbs as select * from scott.emp;
Table created.
SQL> drop table t1;
Table dropped.
SQL> show recycle;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$nTKLacW1QjzgQAoKCgoJog==$0 TABLE 2011-02-27:01:11:59
SQL> create table t1 tablespace mytbs as select * from scott.emp;
Table created.
SQL> show recycle;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$nTKLacW1QjzgQAoKCgoJog==$0 TABLE 2011-02-27:01:11:59
SQL> insert into t1 select * from t1;
14 rows created.
SQL> /
...........
1792 rows created.
SQL> show recycle;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$nTKLacW1QjzgQAoKCgoJog==$0 TABLE 2011-02-27:01:11:59
SQL> insert into t1 select * from t1;
3584 rows created.
SQL> /
7168 rows created.
SQL> /
insert into t1 select * from t1
*
ERROR at line 1:
ORA-01653: unable to extend table SYS.T1 by 128 in tablespace MYTBS
SQL> show recycle;
SQL>
即使数据文件可以拓展 也会清除回收站
SQL> alter database datafile '/u01/oracle/oradata/ora10g/mytbs01.dbf' autoextend on ;
Database altered.
SQL> drop table t1;
Table dropped.
SQL> show recyc;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$nTKLacW2QjzgQAoKCgoJog==$0 TABLE 2011-02-27:01:21:27
SQL> create table t1 tablespace mytbs as select * from scott.emp;
Table created.
SQL> show recyc;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$nTKLacW2QjzgQAoKCgoJog==$0 TABLE 2011-02-27:01:21:27
SQL> insert into t1 select * from t1;
14 rows created.
SQL> /
...................
3584 rows created.
SQL> show recyc;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$nTKLacW2QjzgQAoKCgoJog==$0 TABLE 2011-02-27:01:21:27
SQL> /
7168 rows created.
SQL> show recyc;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$nTKLacW2QjzgQAoKCgoJog==$0 TABLE 2011-02-27:01:21:27
SQL> /
14336 rows created.
SQL> show recyc;
SQL>
有些应用,会频繁地创建并删除表,如果这个时候打开这项功能,就会在回收站中产生很多的垃圾信息,如果需要,可以根据情况关闭这项功能。
[启用&关闭回收站]
ALTER SESSION SET recyclebin = ON;
ALTER SYSTEM SET recyclebin = ON;
ALTER SESSION SET recyclebin = OFF;
ALTER SYSTEM SET recyclebin = OFF;
测试2: --->部分的DML操作恢复
update t1 set id=1; 默认15分钟内就可闪回show parameter undo_retention; 该参数保存了回滚段数据保存的秒时间
可以闪表到 undo_retention限制历史时间内:(10g开始正式支持)
alter table t1 enable row movement; 打开表的行移动(实现完之后再disable)
flashback table t1 to timestamp(sysdate-15/1440); 从回滚取出数据或者(to scn XX )
alter table t1 disable row movement;
SQL> create table t1 as select OWNER,OBJECT_NAME from all_objects where rownum<2;
SQL> select * from t1;
OWNER OBJECT_NAME
------------------------------ ------------------------------
SYS ICOL$
SQL> create index i_objectidon on t1 (owner);
SQL> select a.table_owner,a.table_name,a.index_name,a.status from user_indexes a where a.table_name='T1';
TABLE_ TABLE_N INDEX_NAME STATUS
------ ------- ------------------------------ --------
TEST1 T1 I_OBJECTIDON VALID
TEST1 T1 PK_T1 VALID
SQL> select current_scn from v$database; ---->--DML 操作前scn
CURRENT_SCN
-----------
6213312590
SQL> select to_char(sysdate,'yyyy-mm-dd HH24:MI:SS') from dual; ---DML 操作前时间
SYSDATE
-------------------
2013-04-11 17.34.47
SQL> insert into t1 values('A','B');
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from t1 as of timestamp sysdate;
OWNER OBJECT_NAME
------------------------------ ------------------------------
A B
SYS ICOL$
SQL> select * from t1 as of timestamp sysdate-10/1440 ;
OWNER OBJECT_NAME
------------------------------ ------------------------------
SYS ICOL$
SQL> select * from t1 as of scn 6213312590; ---DML 操作前scn
OWNER OBJECT_NAME
------------------------------ ------------------------------
SYS ICOL$
SQL> select current_scn from v$database; ---DML 操作后scn
CURRENT_SCN
-----------
6213312684
SQL> select * from t1 as of scn 6213312684; ---DML 操作后scn的数据
OWNER OBJECT_NAME
------------------------------ ------------------------------
A B
SYS ICOL$
都用起来很方便 但as of timestamp缺点是时间精缺度不足
比如问题发生后,你每次执行闪查都是以当前时间为基线做运算
当前时间又在不断流逝 所以说精确度不足
所以建议采用 as of scn
SCN历史的数字是固定的.这使我们查询就更容易定点了
获取当前系统SCN的方法
9I; SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
6213312926
10G:SQL> select current_scn from v$database;
CURRENT_SCN
-----------
6213312924
查看SCN和时间对应关系
SQL> select SCN,TIME_DP from smon_scn_time; --只有sys用户可以查询
这个表中存储 每间隔5分钟存储一次
每隔5分钟,系统产生一次系统时间标记与scn的匹配并存入sys.smon_scn_time表,
该表中记录了最近1440个系统时间标记与scn的匹配记录,由于该表只维护了最近的1440条记录,
因此如果使用as of timestamp的方式则只能flashback最近5天内的数据
(假设系统是在持续不断运行并无中断或关机重启之类操作的话)。
所以在Oracle9iR2中,表属性修改时间和flashback时间差至少应为5分钟。否则就会出现ORA-01466错误。
到了10G后虽然这个表记录的还是间隔5分,但多了TIM_SCN_MAP字段记录
系统每3-6秒钟左右更新一次SCN与时间的对应 这个时间对人类操作可以忽略了
时间和scn互换函数
SQL>SQL> select scn_to_timestamp((select current_scn from v$database)) from dual;
SCN_TO_TIMESTAMP((SELECTCURRENT_SCNFROMV$DATABASE))
---------------------------------------------------------------------------
11-4月 -13 05.51.17.000000000 下午
SQL> select timestamp_to_scn((select scn_to_timestamp((select current_scn from v$database)) from dual)) SCN,(select current_scn from v$database) 当前SCN from dual;
SCN 当前SCN
---------- ----------
6213313313 6213313319
恢复; 闪回DML数据是使用回滚段进行恢复
SQL> flashback table t1 to scn 6213312590;
*
第 1 行出现错误:
ORA-08189: 因为未启用行移动功能, 不能闪回表
SQL> alter table t enable row movement; ----> rowmove就是个允许Oracle修改rowid开关,插入数据时会为该条数据分配唯一rowid并且不变,要启用闪回功能必须开启可修改rowid功能打开之后如果行移动了,就会有影响,如果行没移动,就没有影响
表已更改。
SQL> flashback table t1 to scn 6213312590; ----->恢复到增加前的scn
闪回完成。
SQL> select * from t1 ;
OWNER OBJECT_NAME
------------------------------ ------------------------------
SYS ICOL$
SQL> flashback table t1 to scn 6213312684; ----->取消刚刚的恢复 恢复到增加后的scn
闪回完成。
SQL> select * from t1 ;
OWNER OBJECT_NAME
------------------------------ ------------------------------
A B
SYS ICOL$
SQL> flashback table t1 to timestamp(sysdate-1/10); ----->恢复到增加前的时间段
闪回完成。
SQL> select * from t1 ;
OWNER OBJECT_NAME
------------------------------ ------------------------------
SYS ICOL$
SQL> flashback table t1 to timestamp(sysdate-10/1400); ---->取消刚刚的恢复 恢复到增加后的scn
闪回完成。
SQL> select * from t1 ;
OWNER OBJECT_NAME
------------------------------ ------------------------------
A B
SYS ICOL$
结论得出:只要undo内容足够就可以反复flashback ,恢复某个时间点和scn号
测试:rowmove就是个开关,打开之后如果行移动了,就会有影响,如果行没移动,就没有影响
SQL> select t.*, t.rowid from T1 t ;
OWNER OBJECT_NAME ROWID
------------------------------ ------------------------------ ------------------
SYS ICOL$ AAAY/wAAEAAABkzAAC
SQL> delete from t1;
已删除 1 行。
SQL> commit;
提交完成。
SQL> flashback table t1 to timestamp(sysdate-1/10);
闪回完成。
SQL> select t.*, t.rowid from T1 t;
OWNER OBJECT_NAME ROWID
------------------------------ ------------------------------ ------------------
SYS ICOL$ AAAY/wAAEAAABkzAAA
SQL>
结论:enable row movement 可能导致索引失效,触发器一定会失效(网上说的还未测试),行移动就会有影响,如果没移动,就没影响
疑问:
恢复区没有flashback_on 为什么可以恢复表和恢复DML表?
答:只有 flashback database操作依赖于flashback log (存储在flashback area中,需要数据库 flashback_on)
其它的 flashback操作(比如flashback query )(flashback tables/DML tables)都依赖于 undo数据,与数据库flashback on还是 off无关。
V$FLASHBACK_DATABASE_LOG显示闪回数据的信息,用来评估当前负载下需要的闪回空间
Name Description
---------------------------------- --------------------------------------------------
OLDEST_FLASHBACK_SCN Lowest system change number (SCN) in the flashback data, for any incarnation 闪回数据最小的 scn
OLDEST_FLASHBACK_TIME Time of the lowest SCN in the flashback data, for any incarnation闪回数据最小的时间
RETENTION_TARGET Target retention time (in minutes) 闪回保留时间
FLASHBACK_SIZE Current size (in bytes) of the flashback data 闪回数据大小
ESTIMATED_FLASHBACK_SIZE Estimated size of flashback data needed for the current target retention 评估满足当前闪回保留时间,需要的闪回空间的大小
V$FLASHBACK_DATABASE_STAT 显示数据库收集到的闪回信息
Name Description
---------------------------------- --------------------------------------------------
BEGIN_TIME Beginning of the time interval 一段时间间隔的起始时间
END_TIME End of the time interval 一段时间间隔的结束时间
FLASHBACK_DATA Number of bytes of flashback data written during the interval 一段时间内闪回数据的大小 (bytes)
DB_DATA Number of bytes of database data read and written during the interval一段时间内数据库读写大小 (bytes)
REDO_DATA Number of bytes of redo data written during the interval 一段时间内 redo 数据的大小(bytes)
ESTIMATED_FLASHBACK_SIZE Value of ESTIMATED_FLASHBACK_SIZE in V$FLASHBACK_DATABASE_LOG at the end of the time interval 一段时间间隔的结束时,评估需要闪回空间的大小
未开闪回,drop table T1; flashback table t1 to before drop; √;flashback database to timestamp(sysdate-1/1465); X
本文博客
http://blog.sina.com.cn/s/blog_bba8a5b40101bdhu.html