继续转载,三思不会追究我盗版吧.
http://space.itpub.net/7607759/action-spacelist
[@more@]简单来讲,如果我们把flashback query看做是恢复记录,则flashback table就是用来恢复表的(由于记录是以表为载体存储,因此flashback table也应该看做是恢复记录,只不过相对于flashback query而言,其粒度更大一些),同时呢,在Oracle10g中又新引入了一个叫做Recycle Bin的功能(主要针对表及其关联的对象,比如索引约束啥的),被删除的表并非真正删除,而是先通过修改数据字典的方式,将其改名并放入recyclebin,如果要恢复recycle bin中对象的话,借助flashback table是最简便的方式。除此之外,flashback table也提供了类似flashback query中as of scn/timestamp的方式,借助undo数据,直接将现有的表恢复到某个指定的时间点或scn时的状态。
下面分别举例:
2.1、从RECYCLEBIN中恢复
要恢复recyclebin中的表,注意语句如下:Flashback table [objName] to before drop,这个obj_name即可以是表名,也可以是recyclebin中的对象表(支持同时操作多个表,表名之间以逗号分隔即可),由于该项功能是恢复被删除表,因此官方对其还有另外一称谓:flashback drop。
下面举个例子,从recyclebin中恢复一个被删除的表:
JSSWEB> select object_name,original_name from recyclebin;
OBJECT_NAME ORIGINAL_NAME
------------------------------ --------------------------------
BIN$u/7I62WxS12jMVO358SFgw==$0 JSS_TB3
JSSWEB> select object_name,original_name from recyclebin;
OBJECT_NAME ORIGINAL_NAME
------------------------------ --------------------------------
BIN$u/7I62WxS12jMVO358SFgw==$0 JSS_TB3
JSSWEB> flashback table jss_tb3 to before drop;
闪回完成。
JSSWEB> select object_name,original_name from recyclebin;
未选定行
Flashback table语句同时提示了一个rename to [newTBname]的子句,如果要恢复的表在当前schema中已经存在同名的表,建议你在恢复时通过rename to 子句为待恢复的表指定一个新的表名,不然数据库会报ORA-38312错误,再举个例子:
JSSWEB> drop table jss_tb3;
表已删除。
JSSWEB> create table jss_tb3 as select *from jss_tb1;
表已创建。
JSSWEB> flashback table jss_tb3 to before drop;
flashback table jss_tb3 to before drop
*
第 1 行出现错误:
ORA-38312: 原始名称已被现有对象使用
你看,正如其提示的那样,该表被删除之后,又执行过创建同名表的操作,因此恢复的时候就会报错,怎么办呢,用rename to.....
JSSWEB> flashback table jss_tb3 to before drop rename to jss_tb3_bak;
闪回完成。
某些时候,我们要处理的表并不是被意外删除,而是被反复修改过多次,希望能回复到之前的某个时间点,通过前面的学习,你一定会说没问题啊,借助flashback query就可以,没错,flashback query确实可以,但flashback query只是查询出记录,如果想做恢复还需要写出相应的insert或update,也许还需要相当多的where条件做判断,一个不甚,可能恢复的数据就是错误的。老板又没在跟儿前站着,我们没必要在这个时刻用这种方式展示我们娴熟的指法,因此,我们需要更高效更严谨更简便的方式:flashback table tbname to scn/timestamp,助你达成梦想,详情请咨询,o错了,应该是详情请接着往下看。
Scn和timestamp的用法通过前面flashback query的学习大家应该都比较熟了,flashback table中指定scn或timestamp的用法与上相同,举个例子吧:
有数据如下:
JSSWEB> select *from jss_tb1;
ID VL
---------- --------------------
6 F
7 G
8 H
9 I
11 K
12 L
13 M
14 N
15 O
10 J
记录下当前系统scn(如果不知道确切的scn,恢复时只能通过时间,但正如前文中讲到的,时间并不精确,如果通过指定timestamp恢复的话,需要你清楚了解所做的操作大概是在什么时间)
JSSWEB> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
593480
我们对该表做些操作:
JSSWEB> update jss_tb1 set id=id+100 where id>10;
已更新5行。
JSSWEB> insert into jss_tb1 values (21,'Z');
已创建 1 行。
JSSWEB> delete jss_tb1 where id=8;
已删除 1 行。
JSSWEB> commit;
提交完成。
JSSWEB> select *from jss_tb1;
ID VL
---------- --------------------
21 Z
6 F
7 G
9 I
111 K
112 L
113 M
114 N
115 O
10 J
已选择10行。
这些都属于常规操作,如果最终发现这些操作都属于误操作,需要恢复回表最初的形式,借助flashback query当然可以实现:
JSSWEB> select *from jss_tb1 as of scn 593480;
ID VL
---------- --------------------
6 F
7 G
8 H
9 I
11 K
12 L
13 M
14 N
15 O
10 J
已选择10行。
查询能够写出来,就一定能将表更新回去,不过既使是针对我们测试时所做过的简单操作(添加、删除、修改),更新的语句就已经需要写的很复杂了,因为我们需要分别判断添加、删除、修改过的记录。
幸好,我们还有flashback table,因此我们只需要指定一个scn或timestamp即可。
JSSWEB> flashback table jss_tb1 to scn 593480;
闪回完成。
JSSWEB> select *from jss_tb1;
ID VL
---------- --------------------
6 F
7 G
8 H
9 I
11 K
12 L
13 M
14 N
15 O
10 J
已选择10行。
所有记录均已回复到指定scn时的状态。
3、注意事项
a.基于undo的表恢复,被恢复的表必须启用row movement,不然会报ORA-08189错误,关于row movement的相关知识,三思在"全面学习分区表及分区索引"一文中有过阐述,这里就不多费口舌了。
要查看某表是否启用row movement,可以到user_tables中查询(或all_tables,dba_tables),例如:
JSSWEB> select row_movement from user_tables where table_name='JSS_TB1';
ROW_MOVE
--------
ENABLED
要启用或禁止某表row movement,可以通过下列语句:
--启用
JSSWEB> ALTER TABLE JSS_TB1 ENABLE ROW MOVEMENT;
表已更改。
--禁止
JSSWEB> ALTER TABLE JSS_TB1 DISABLE ROW MOVEMENT;
表已更改。
b. 基于undo的表恢复,需要注意前文制约因素1.5.3中提到的ddl的影响。
c. 基于undo的表恢复,flashback table实际上做的也是dml操作(会在被操作的表上加dml锁),因此还需要注意triggers对其的影响,默认情况下,flashback table to scn/timestamp在执行时会自动disable掉与其操作表相差的triggers,如果你希望在此期间trigger能够继续发挥做用,可以在flashback table后附加 ENABLE TRIGGERS子句。
d. 基于undo的表恢复,索引会自动维护,但统计信息并不会恢复到指定的时间点。
e. 基于recycle bin的表恢复,flashback drop不能恢复参照完整性,这很容易理解,毕竟在该表删除之后,其被参照表是否有修改它已经无法控制了,因此如果该表有主外键约束的话,恢复之后,该约束是disable状态,需要dba手工处理。
f. 基于recycle bin的表恢复,所操作的表必须是存在于本地管理表空间中。Flashback drop不能恢复字典管理表空间中被删除的表,也不能恢复系统表。
g. 基于recycle bin的表恢复,被恢复的表的关联对象,比如其索引啦,约束的名称不会自动恢复成删除前的名称,而是系统自动生成的名称,如果你对表的索引约束有相关命名规范,那在恢复表之后,需要dba手工将索引约束等改名。
h. 当删除表时,信赖于该表的物化视图也会同时删除,但是由于物化视图并不会被放入recycle bin,因此当你执行flashback table to before drop时,也不能恢复依赖其的物化视图,需要dba手工介入重新创建。
i. 相对于被删除的表而言,当数据文件空间不足时,oracle会首先清理被删除表的索引,因此假如你执行flashback table to before drop而发现缺少索引可能是正常的,说明你显然错过了最佳的恢复时机。
j. Flashback table命令支持同时操作多个表,表名中间以逗号分隔即可,如果你执行一条flashback table命令时同时指定了多个表,要记住单个flashback table是在同一个事务中,因此这些表的恢复操作要么都成功,要么都失败。
附B:
提示:什么是Recycle Bin(回收站)
在三思之前的一些笔记中,我们曾经数次提到过这个东西,当然那些文章中介绍的都比较简单,仅仅只是一笔带过,这里呢也不准备太细致的讲解和介绍,因为这个东西确实很简单,你可以把它看成是windows中的回收站,在windows中我们删除一些文件的话,windows并非直接删除,而是直接将文件移至回收站文件夹下,Oracle中也是一样,当你删除一个表的时候,数据库并非真正立刻执行删除的操作,而是将其重命名,连同其相关联的一些对象,如表的索引、约束等统统放入recycle bin。
每一个用户都会有一个自己的recycle bin,就像windows中每个盘符下都会有一个recycle目录(对应回收站)一样,要查看recycle bin中对象,直接:
JSSWEB> select *from recyclebin;
即可。
我们都知道在windows中删除的同时如果按着Shift则文件将会被真正删除(不钻牛角尖,我是说windows将其删除,至于你通过recovery之类工具还可再将其从磁盘恢复不再此例范围之内),那么对于oracle是否也有一种方式能够让我们执行的删除不再被放入回收站呢?答案当然是肯定,而且oracle又提供了不止一种方式(咦,为什么要说又呢)~~~~~
第一种方式:删除时指定purge参数(等同于我们在windows中按着shift删除),例如:
JSSWEB> drop table jss_tb3 purge;
表已删除。
JSSWEB> select *from recyclebin;
未选定行
第二种方式:修改初始化参数recyclebin=off,例如:
JSSWEB> create table jss_tb3 (id number);
表已创建。
JSSWEB> show parameter recyclebin
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
recyclebin string on
JSSWEB> alter session set recyclebin = off;
会话已更改。
JSSWEB> show parameter recyclebin
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
recyclebin string OFF
JSSWEB> drop table jss_tb3;
表已删除。
JSSWEB> select *from recyclebin;
未选定行
这里我们只针对当前session,如果希望针对整个实例,通过alter system set recyclebin=off,或者修改pfile中recyclebin参数,将其设置为off。这样所有drop table操作都会直接删表,而不再转移到recycle bin,这就相当于禁用了recycle bin功能,如果某天你又想启用该功能,只需要将该初始化参数设置为on即可。
对于已存在于recyclebin字典中的对象,如果想彻底删除该怎么办呢,Oracle再一次提供了多种方式,以及多种粒度来执行删除。
先建个测试用的环境:
JSSWEB> create table jss_tb3 (id number);
表已创建。
JSSWEB> alter session set recyclebin=on;
会话已更改。
JSSWEB> select object_name,original_name from recyclebin;
OBJECT_NAME ORIGINAL_NAME
------------------------------ --------------------------------
BIN$JhA057bpRxKICIe/vNahyQ==$0 JSS_TB3
A.Purge指定表,例如:
JSSWEB> purge table jss_tb3;
或
JSSWEB> purge table "BIN$JhA057bpRxKICIe/vNahyQ==$0";
B.Purge指定表空间,例如:
JSSWEB> purge tablespace webtbs;
C.清空recyclebin,例如:
JSSWEB> purge recyclebin;
除上述的三种之外,还有一种方式就是删除recycle bin中对象所属用户或所在表空间,这样甭管你是否purge,recycle bin都会被清空,不过这种方式好像狠了点儿,慎用啊~~~~~
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/271283/viewspace-1008087/ ,如需转载,请注明出处,否则将追究法律责任。