简易总结:
1、如果删除了表可以考虑flashback drop (表不在system表空间)
2、如果是一个表几条记录可以考虑flashback table(sys用户下的表不支持)
3、如果涉及的表比较多,那么可以考虑flashback database,但要确认是否启用了闪回数据库,默认未打开
4、如果修改过多次,那么可以考虑使用flashback transaction query确认,使用UNDO_SQL来恢复
一、闪回介绍
Flashback 技术是以Undo segment中的内容为基础的, 因此受限于UNDO_RETENTON参数。要使用flashback 的特性,必须启用自动撤销管理表空间。(undo_management string AUTO)
在Oracle 10g中, Flash back家族分为以下成员: Flashback Database, Flashback Drop,Flashback Query(分Flashback Query,Flashback Version Query,Flashback Transaction Query三种)和Flashback Table。
在Oracle 11g里又出了一个新特性:Oracle Flashback Data Archive. FDA通过将变化数据另外存储到创建的闪回归档区(Flashback Archive)中,以和undo区别开来,这样就可以为闪回归档区单独设置存储策略,使之可以闪回到指定时间之前的旧数据而不影响undo策略。
1、闪回的种类
1)flashback drop 依赖回收站recyclebin 删除表了,闪回到DROP表之前
有两种情况,表是不进回收站的:第一种原始表在SYSTEM表空间。第二种当前对象在DMT表空间中删除。
删除表时,相关的索引,触发器也被删除,函数,存储过程则不会,所以函数或者存储过程等就需要使用Flashback Query来实现。
SQL> drop table ttt;
Table dropped.
SQL> select * from user_recyclebin;
。。。。。。。
SQL> flashback table ttt to before drop;如原表名已占用,只能重命名(flashback table ttt to before dorp rename to xx)
Flashback complete.
SQL> flashback table "BIN$vYuv+g9fTi2exYP9X2048Q==$0" to before drop; 这样也行。如果有重名的话
SQL> select * from ttt;
---------- ----------
Flashback Drop需要注意的地方:
1). 只能用于非系统表空间和本地管理的表空间
2). 对象的参考约束不会被恢复,指向该对象的外键约束需要重建。
3). 对象能否恢复成功,取决与对象空间是否被覆盖重用。
4). 当删除表时,信赖于该表的物化视图也会同时删除,但是由于物化视图并不会被放入recycle bin,因此当你执行flashback table to before drop 时,也不能恢复依赖其的物化视图,需要dba手工介入重新创建。
5). 对于Recycle Bin中的对象,只支持查询.
2)flashback table (sys用户下的表不支持)删除表中的数据后,闪回到删除数据之前。可以处理错误删除或修改数据
依赖UNDO表空间,11G之后增加了,可以单独设置闪回表空间。设置保存多少时间。
Flashback table 命令支持同时操作多个表,如:flashback table a,b ,c要么都成功,要么都失败,同一事物中。
例子:
SQL> delete t1 where id='1';
1 row deleted.
SQL> commit;
SQL> flashback table t1 to scn 1946891;
flashback table t1 to scn 1946891
ERROR at line 1:
ORA-08189: cannot flashback the table because row movement is not enabled
SQL> alter table t1 enable row movement; 因为闪回来的数据ROWID会变化,那么必须要启用ROW MOVEMENT,禁用DISABLE
Table altered.
SQL> flashback table t1 to scn 1946891;
Flashback complete.
SQL> select * from t1;
ID NAME
---------- ----------------------------------------
查询是否启动了row movment
SQL> select row_movement from user_tables where table_name='C';
ROW_MOVE
--------
ENABLED
3)flashback query闪回查询可以处理行的删除.
Flashback Query 是利用多版本读一致性的特性从UNDO 表空间读取操作前的记录数据。依赖于UNDO,查询数据方式只需要在标准查询语句的表名后面跟上as of timestamp(基于时间)或as of scn(基于scn)即可
语法:select * from tablename as of timestamp|scn
例子: select * from t as of scn 696842 10G才支持,9I一般使用dbms_flashback这个包里的函数来实现
select * from test1 as of timestamp to_timestamp('12-01-13 16:59:29','YY-MM-DD hh24:mi:ss');
· flashback query 对v$tables,x$tables等动态性能视图无效,不过对于dba_*,all_*,user_*等数据字典是有效的。
该特性也完全支持访问远端数据库,比如select * from tbl@dblink as of scn 3600;的形式。
· as of timestamp的确非常易用,但是在某些情况下,我们建议使用as of scn的方式执行flashback query,比如需要对多个相互有主外键约束的表进行恢复时,如果使用as of timestamp 的方式,可能会由于时间点不统一的缘故造成数据选择或插入失败,通过scn方式则能够确保记录的约束一致性。
(SCN 与 timestamp关系见下面的补充)
4)flashback vession query闪回版本查询。主要用来查询
Flashback Query 只能看到某一点的对象状态, Oracle 10g引入的Flashback Version Query可以看到过去某个时间段内,记录是如何发生变化的。版本查询是通过一个伪列来查询:ORA_ROWSCN(Oracle 10g新增的),暂且把它看作是记录最后一次被提交修改时的SCN。
例子:
04:32:17 SQL> insert into t1 values(5,6);
1 row created.
04:32:43 SQL> commit;
Commit complete.
04:32:47 SQL> insert into t1 values(7,8);
1 row created.
04:32:58 SQL> commit;
Commit complete.
04:33:01 SQL> insert into t1 values(9,10);
1 row created.
04:33:17 SQL> insert into t1 values(11,12);
1 row created.
当前表的版本查询:
sql>select versions_xid,versions_operation,versions_startscn,versions_starttime,
versions_endscn,versions_endtime,id,name
from test1.t1 versions between scn minvalue and maxvalue
sql>update test1.t1 set id='111' where id='11'
select current_scn from v$database; 查询当前SCN
SELECT ID,NAME,VERSIONS_STARTSCN STARTSCN,VERSIONS_ENDSCN ENDSCN,VERSIONS_OPERATION OPERATION,VERSIONS_XID XID
FROM T1 VERSIONS BETWEEN SCN 2942841 AND 2942947;
--VERSIONS_STARTSCN:该条记录操作时的SCN,如果为空,表示该行记录是在查询范围外创建的
--VERSIONS_ENDSCN:该条记录失效时的SCN,如果为空,说明记录在这段时间无操作,或者已经被删数,配合VERSIONS_OPERATION
--VERSIONS_OPERATION:I表示insert、D表示delete、U表示update
--VERSIONS_XID:该操作的事务ID
5)flash transaction query 闪回事务查询
Flashback Transaction Query也是使用UNDO信息来实现。利用这个功能可以查看某个事务执行的所有变化,它需要访问flashback_transaction_query视图,这个视图的XID列代表事务ID,利用这个ID可以区分特定事务发生的所有数据变化。
select * from flashback_transaction_query这个数据量来源于UNDO表空间,一般生产库数据量非常大
例子:select * from flashback_transaction_query where xid='06001D0078030000'
就可以查到UNDOSQL:update "TEST1"."T1" set "ID" = '11' where ROWID = 'AAANIhAAGAAAAAUAAD';这样执行这条UNDO sql就可以完全回退。
查询XID示例:
SQL> insert into B values(3);
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from B;
ID
----------
1
2
3
查看视图,每个事务都对应相同的XID
SQL>Select xid,operation,commit_scn,undo_sql from flashback_transaction_query
where xid in (Select versions_xid from B versions between scn minvalue and maxvalue);
或者
SQL>select xid,commit_scn,commit_timestamp,operation,undo_sql
from flashback_transaction_query q
where q.xid in(select versions_xid from B versions
between scn 413946 and 413959);
XID OPERATION COMMIT_SCN UNDO_SQL
-----------------------------------------------------------------------------------------------------
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('4');
03001C006A020000 DELETE
insert into "SYS"."B"("ID") values ('3');
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('2');
SQL> DESC FLASHBACK_TRANSACTION_QUERY --能获得这个事务执行时的很多信息,包括UNDO语句
Name
----------------- -------- ------------
XID RAW(8) --事务ID,对应Versions Query中的VERSIONS_XID
START_SCN NUMBER --事务开始时的SCN
START_TIMESTAMP DATE --事务开始时间
COMMIT_SCN NUMBER --事务提交时的SCN,该列为空的话,说明事务为活动事务
COMMIT_TIMESTAMP DATE --事务提交时间
LOGON_USER VARCHAR2(30) --操作用户
UNDO_CHANGE# NUMBER --UNDO SCN
OPERATION VARCHAR2(32) --执行操作,有几个值:Delete、Insert、Update、B、UNKNOWN
TABLE_NAME VARCHAR2(256)--DML操作对象的表名
TABLE_OWNER VARCHAR2(32) --表的属主
ROW_ID VARCHAR2(19) --DML操作记录的行地址
UNDO_SQL VARCHAR2(4000)--撤销该操作对应的SQL
补充:
1、回收站
初始化参数recyclebin 用于控制是否启用recyclebin功能,缺省是ON,可以使用OFF关闭
禁用及开启该功能:
SQL> alter system set recyclebin=off;
SQL> alter system set recyclebin=on;
查看回收站里的对象:
SQL> show recyclebin
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
A
查看recyblebin对象里的内容:
SQL> select * from "BIN$RWXQQcTPRde0ws4h9ewJcg==$0";
也可以手动的删除Recycle Bin占用的空间:
1). Purge tablespace tablespace_name :用于清空表空间的Recycle Bin
2). Purge tablespace tablespace_name user user_name:清空指定表空间的Recycle Bin中指定用户的对象
3). Purge recyclebin: 删除当前用户的Recycle Bin中的对象
4). Purge dba_recyclebin: 删除所有用户的Recycle Bin中的对象,该命令要sysdba权限
5). Drop table table_name purge: 删除对象并且不放在Recycle Bin中,即永久的删除,不能用Flashback恢复。
6). Purge index recycle_bin_object_name:当想释放Recycle bin的空间,又想能恢复表时,可以通过释放该对象的index所占用的空间来缓解空间压力。因为索引是可以重建的。