一、利用闪回被drop掉的表
一个不该发生的情况:用户删除了一个非常重要的表 ― 当然是意外地删除 ― 并需要尽快地恢复。使用 Oracle Database 10g 中的闪回表特性,可以毫不费力地恢复被意外删除的表。被删除的表及其相关对象被放置在一个称为"回收站"的逻辑容器中,它类似于PC机中的回收站。但是,对象并没有从它们原先所在的表空间中删除;它们仍然占用那里的空间。回收站只是一个列出被删除对象目录的逻辑结构。
当前模式中的表
select *
from user_tables
-----
TEACHER
PRODUCT
TEST_FOR_CHINESE
SMS_SEND_DELAY
drop掉其中一个表:
SQL> drop table teacher
Table dropped
此时用户下的表
SQL> select *
2 from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
PRODUCT TABLE
TEST_FOR_CHINESE TABLE
SMS_SEND_DELAY TABLE
BIN$sJ6jp/l3TXa6wfHO1G7IsA==$0 TABLE
表 TEACHER 已不存在,但是请注意出现新表BIN$sJ6jp/l3TXa6wfHO1G7IsA==$0。这就是所发生的事情:被删除的表 TEACHER 并没有完全消失,而是重命名为一个由系统定义的名称。它存在于同一个表空间中,具有与原始表相同的结构。如果在该表上定义了索引或触发器,则它们也被重命名,使用与表相同的命名规则。任何相关源(如过程)都失效;原始表的触发器和索引被改为放置在重命名的表 BIN$sJ6jp/l3TXa6wfHO1G7IsA==$0 上,保持被删除表的完整对象结构。
SQL> show recyclebin;
SQL> /
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
PRODUCT TABLE
TEST_FOR_CHINESE TABLE
SMS_SEND_DELAY TABLE
BIN$sJ6jp/l3TXa6wfHO1G7IsA==$0 TABLE
可以看到是一样的,tab和recyclebin中所有的对象。
flashback table TEACHER to before drop
表放在回收站里并不在原始表空间中释放空间。要释放空间,可以使用以下命令清空回收站:
PURGE RECYCLEBIN;
如果希望完全删除该表而不需要使用闪回特性,该怎么办?在这种情况下,可以使用以下命令永久删除该表:
DROP TABLE RECYCLETEST PURGE;
二、回收站的管理
如果经常性的没有实际删除表 ― 因而没有释放表空间 ― 那么当被删除的对象占用了所有空间时,会发生什么事?
答案:这种情况根本不会出现。当表空间被回收站数据完全占满,以至于必须扩展数据文件来容纳更多数据时,可以说表空间处于"空间压力"情况下。此时,对象以先进先出的方式从回收站中自动清除。在删除表之前,相关对象(如索引)被删除。
同样,空间压力可能由特定表空间定义的用户限额而引起。表空间可能有足够的空余空间,但用户可能将其在该表空间中所分配的部分用完了。在这种情况下,Oracle 自动清除该表空间中属于该用户的对象。
以下几种方法可以手动控制回收站。如果在删除名为teacher的特定表之后需要从回收站中清除它,可以执行purge table teacher;
①DROP TABLE teacher PURGE或者使用其回收站中的名称PURGE TABLE "BIN$sJ6jp/l3TXa6wfHO1G7IsA==$0";
此命令将从回收站中删除表 TEST 及所有相关对象,如索引、约束等,从而节省了空间。
如果仅仅要从回收站中永久删除索引,则可以使用以下命即可:
purge index iDX_1;
②清除某个表空间的回收站中的所有对象。
PURGE TABLESPACE USERS;
③清除特定表空间中特定用户清空回收站
PURGE TABLESPACE USERS USER RUYING;
其他的如PURGE RECYCLEBIN PURGE DBA_RECYCLEBIN等
三、多次drop表的闪回:多次创建和删除同一个表
配置:
版本1:
create table teacher (id number(10),
name varchar2(40),
mobile varchar2(40)
);
/
insert into teacher
values(1,'小一','15466666666');
/
drop table teacher;
版本2:
create table teacher (id number(10),
name varchar2(40),
mobnum varchar2(40)
);
/
insert into teacher
values(1,'小二','15988888888');
/
drop table teacher;
版本3:
create table teacher (id number(10),
name varchar2(40),
address varchar2(40)
);
/
insert into teacher
values(1,'小二','东方瑞士');
/
drop table teacher
/
-------默认情况下恢复到最近删除之前的一个版本也就是版本3 address表结构
SQL> flashback table teacher to before drop;
Done
SQL> desc teacher;
Name Type Nullable Default Comments
------- ------------ -------- ------- --------
ID NUMBER(10) Y
NAME VARCHAR2(40) Y
ADDRESS VARCHAR2(40) Y
需要获得之前的删除版本
恢复到版本2
SQL> FLASHBACK TABLE teacher TO BEFORE DROP RENAME TO teacher2;
Done
SQL> desc teacher2;
Name Type Nullable Default Comments
------ ------------ -------- ------- --------
ID NUMBER(10) Y
NAME VARCHAR2(40) Y
MOBNUM VARCHAR2(40) Y
恢复到版本1
SQL> FLASHBACK TABLE teacher TO BEFORE DROP RENAME TO teacher1;
Done
SQL> desc teacher1;
Name Type Nullable Default Comments
------ ------------ -------- ------- --------
ID NUMBER(10) Y
NAME VARCHAR2(40) Y
MOBILE VARCHAR2(40) Y
当然也可以使用这样直接使用回收站中名字的办法恢复。
FLASHBACK TABLE "BIN$3FvpnIgtS9SgjNsbyUwKUg==$0" TO BEFORE DROP RENAME TO teacher2;
/
FLASHBACK TABLE "BIN$b29NtcUoQsiGQh0/UvWtGA==$0" TO BEFORE DROP RENAME TO teacher1;
当然也可以闪回到某个时间点
alter table teacher enable row movement/flashback table teacher TO TIMESTAMP to_timestamp('2010-10-31
19:42:00','yyyy-mm-dd hh24:mi:ss')。
四、查询闪回
如果错误的提交了修改操作之后,需要查看所修改行的原来的值得,可以使用查询闪回。当然如果需要恢复修改之前的样子,
可以直接闪回表闪回到某个时间点或者某个版本,也可以利用查询闪回后的结果进行手工的一些修改。
①授权grant execute on sys.dbms_flashback to ruying;
具体包的用法可以自己进到包体中看,只有3个过程,一个方法,比较简单。
②原始状态
SQL> select *
from teacher;
ID NAME ADDRESS
1 小一 15466666666
③做出改变
insert into teacher
values(2,'小二','东方瑞士');
insert into teacher
values(3,'小三','奥利地');
/
SQL> update teacher
2 set id=id+1;
④实验一下:回到过去
execute dbms_flashback.enable_at_time(sysdate-10/1440);
/
SQL> select *
from teacher;
ID NAME ADDRESS
1 小一 15466666666
⑤回到当下
SQL> exec dbms_flashback.disable();
/
SQL> select *
2 from teacher;
ID NAME ADDRESS
2 小一 15466666666
3 小二 东方瑞士
4 小三 奥利地
闪回查询就是一瞬间可以看到设定的某个时间点的数据状态。
当然也可以用SCN来查询闪回。时间所限就先到这。
五、闪回数据库
闪回操作是根据SCN系统变更号进行的,数据库使用SCN来跟踪对数据进行的修改,所以可以根据SCN进行数据库的闪回,将数据库闪回到一个特定的
SCN时的状态。
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_9011.htm#SQLRF01801
目前个人总结闪回就是利用了回收站和SCN。
六、参考资料
http://www.oracle.com/technology/global/cn/pub/articles/10gdba/week5_10gdba.html
http://www.oracle.com/technology/global/cn/pub/articles/10gdba/week1_10gdba.html
edit on 2010-10-31
七、备忘
SELECT UNDO_SQL
FROM FLASHBACK_TRANSACTION_QUERY
WHERE XID = '000A000D00000029';
select versions_starttime, versions_endtime, versions_xid,
versions_operation, rate
from rates versions between timestamp minvalue and maxvalue
order by VERSIONS_STARTTIME
select rate, versions_starttime, versions_endtime
from rates versions
between timestamp
to_date('12/1/2003 15:57:54','mm yy hh24:mi:ss')
and to_date('12/1/2003 16:57:55','mm yy hh24:mi:ss')