HelloDBA [English]
搜索Internet 搜索 HelloDBABA
  Oracle技术站。email: fuyuncat@gmail.com  MSN: fuyuncat@hotmail.com   acoug  acoug 

Oracle 10G 新特性——闪回表

[English]

作者: fuyuncat

来源: www.HelloDBA.com

日期: 2006-04-07 14:47:10

分享到  新浪微博 腾讯微博 人人网 i贴吧 开心网 豆瓣 淘宝 推特 Facebook GMail Blogger Orkut Google Bookmarks

  

 删除表的恢复

如果某个用户不小心删除了一个十分重要的表,后果将非常严重。在9i中提供的闪回特性只能恢复DML语句造成的影响,而无法恢复DDL语句的影响。DBA只能通过重建一张表,然后从备份数据中导入。

利用Oracle 10G中的闪回表的特性,DBA可以轻松完成这项工作,并将影响降到最小。下面就举一个例子说明:

  • 创建表:

SQL> create table abc (f number(9));

表已创建。

SQL> create index idx_test on abc(f);

索引已创建。

SQL> insert into abc values(1);

已创建 1 行。

SQL> insert into abc values(2);

已创建 1 行。

SQL> insert into abc values(3);

已创建 1 行。

SQL> select * from tab;

TNAME                                TABTYPE         CLUSTERID

------------------                           -------------- ----------

ABC                                   TABLE

SQL> select index_name, index_type, table_name from ind;

INDEX_NAME                    INDEX_TYPE   TABLE_NAME

-------------------                     -------------------  ----------------------

IDX_TEST                         NORMAL      ABC

  • 删除表:

SQL> drop table abc;

表已删除。

SQL> select * from tab;

TNAME                                TABTYPE         CLUSTERID

------------------                           -------------- ----------

BIN$XXUGsbYvSqa8Mrd6GstP+g==$0      TABLE

请注意,在原表abc被删除后,abc没有了,却出现了一张新表BIN$XXUGsbYvSqa8Mrd6GstP+g==$0。这就是Oracle 10G中对删除表的处理,原表实际上并没有完全删除掉,而是被系统重新命名成了一个系统定的新表。它还存在于原先的表空间,并且保持了原有的结构。

依赖于原表的存储过程都失效了。而建在表上的索引和触发器也会被重新命名。

SQL> select index_name, index_type, table_name from ind;

INDEX_NAME                    INDEX_TYPE   TABLE_NAME

-------------------                     -------------------  ----------------------

BIN$1++ilvsQQ7mfPh2pvont5A==$0 NORMAL  BIN$XXUGsbYvSqa8Mrd6GstP+g==$0

被删除的表及其相关对象都会被放置在一个称为recyclebin的逻辑容器中:

SQL> show recyclebin

ORIGINAL NAME    RECYCLEBIN NAME  OBJECT TYPE  DROP TIME

----------------         ----------------------------   ------------   ---------------

ABC      BIN$XXUGsbYvSqa8Mrd6GstP+g==$0 TABLE      2005-08-29:18:03:10

显示了被删除对象的原有名字,删除后的名字,对象类型以及删除时间。

通过使用flashback table语句就可以恢复表!

SQL> flashback table abc to before drop;

闪回完成。

SQL> select * from tab;

TNAME                                TABTYPE         CLUSTERID

------------------                           -------------- ----------

ABC                                   TABLE

这样就轻松的将对象恢复了!

注意,对象被恢复后,它在recyclebin中占用的空间并不会被释放。必须使用PURGERECYCLEBIN来清空占用的空间。

SQL> PURGE RECYCLEBIN;

回收站已清空。

当然,如果想要彻底删除一个对象,让它不占用回收站的空间,可以用以下语句实现:

SQL> DROP TABLE ABC PURGE;

管理回收站

一旦哪些没有被真正删除的对象占满了表空间将会怎样呢?其实答案很简单:如果表空间被回收站中的数据占满了,并且数据文件也无法再扩展了(即产生了表空间压力)。那么回收站中的对象将会以“先入先出”(FIFO)的原则被自动清除掉。并且,依赖表的对象(如索引)将会比表对象先清除。

同样的,当存在用户配额时也会发生表空间压力的情况。当一个用户的配额空间被占满了,尽管此时表空间还可能有足够的空间,系统也会以FIFO的原子释放回收站中属于这个用户的对象。

另外,还有多种途径来手工控制回收站。比如可以用对象的原有名字从回收站中清除指定对象:

PURGE TABLE ABC

或者用对象被删除后系统自动重命名的名字来指定清除它:

PURGE TABLE “BIN$XXUGsbYvSqa8Mrd6GstP+g==$0”

清除表时,同时也会清除依赖这张表的约束,如索引。可以指定只清除表相应的约束,如:

PURGE INDEX IDX_TEST

此外,还可以将整个表空间的回收站内容全部清除:

PURGE TABLESPACE RING

也可以清除某个表空间上的回收站中某个用户的对象:

PURGE TABLESPACE RING USER TEST

当用某个普通用户登录时,只会清除它自己的对象。

PURGE RECYCLEBIN

当以DBA身份登录时,可以清除所有表空间上回收站

PURGE DBA_RECYCLEBIN

表的版本和闪回

一旦一张表被多次删除又重建,该如何恢复呢?

SQL> CREATE TABLE TEST (COL1 NUMBER);

表已创建。

SQL> INSERT INTO TEST VALUES (1);

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> DROP TABLE TEST;

表已删除。

SQL> CREATE TABLE TEST (COL1 NUMBER);

表已创建。

SQL> INSERT INTO TEST VALUES (2);

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> DROP TABLE TEST;

表已删除。

SQL> CREATE TABLE TEST (COL1 NUMBER);

表已创建。

SQL> INSERT INTO TEST VALUES (3);

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> DROP TABLE TEST;

表已删除。

这时,系统在每一次删除时都会在回收站中为这张表重命名一张表:

SQL> select * from tab;

TNAME                                TABTYPE         CLUSTERID

------------------                           -------------- ----------

BIN$IE1x0mwfSe6p6yhLn8/mBw==$0       TABLE

BIN$SUj0n3ghTaSQu0AFGheUYA==$0      TABLE

BIN$khjCqP4fRqeOrE/Eg/XUWQ==$0       TABLE

SQL> show recyclebin

ORIGINAL NAME    RECYCLEBIN NAME  OBJECT TYPE  DROP TIME

----------------         ----------------------------   ------------    ---------------

TEST     BIN$IE1x0mwfSe6p6yhLn8/mBw==$0 TABLE        2005-08-29:20:44:47

TEST     BIN$khjCqP4fRqeOrE/Eg/XUWQ==$0 TABLE        2005-08-29:20:44:47

TEST     BIN$SUj0n3ghTaSQu0AFGheUYA==$0 TABLE        2005-08-29:20:44:46

这时,如果使用flashback table test to before drop就只会最后一次删除的表的状态,即字段col1的内容为3。可以使用以下方式将表闪回并重命名:

SQL> flashback table test to before drop rename to test2;

闪回完成。

SQL> flashback table test to before drop rename to test3;

闪回完成。

SQL> select * from tab;

TNAME                                TABTYPE         CLUSTERID

------------------                           -------------- ----------

TEST                                  TABLE

TEST2                                 TABLE

TEST3                                 TABLE

这时的闪回是以删除的相反顺序闪回的。

所以可以直接指定某一次被删除的表:

SQL> flashback table “BIN$khjCqP4fRqeOrE/Eg/XUWQ==$0” to before drop rename to test2;

闪回完成。

SQL> flashback table “BIN$SUj0n3ghTaSQu0AFGheUYA==$0” to before drop rename to test3;

闪回完成。

需要注意的

表上的对象如索引、触发器在表被闪回后是不会被同时闪回的,而是保持了在回收站中名字。一些依赖这张表的代码对象如视图、存储过程在表被删除后会失效,在表被闪回后不会被自动重新编译,而要手工重新编译他们。

相关的信息被保存在视图USER_RECYCLE中。可以用以下语句来获得这些索引、触发器对象的原有名称:

SQL> SELECT OBJECT_NAME, ORIGINAL_NAME, TYPE

  2  FROM USER_RECYCLEBIN

  3  WHERE BASE_OBJECT = (SELECT BASE_OBJECT FROM USER_RECYCLEBIN

  4  WHERE ORIGINAL_NAME = 'ABC')

  5  AND ORIGINAL_NAME != 'ABC';

OBJECT_NAME                    ORIGINAL_N TYPE

------------------------------               ----------      --------

BIN$1++ilvsQQ7mfPh2pvont5A==$0   IDX_TEST    INDEX

可以用以下方式来恢复索引:

SQL> ALTER INDEX " BIN$1++ilvsQQ7mfPh2pvont5A==$0" RENAME TO IDX_TEST;

一个例外就是位图索引被删除后是不会被保存在回收站中的,也无法从上述视图中查到,需要用其他方式来恢复。

闪回表的其他用途

闪回表功能并不仅仅用于恢复被删除的表。像闪回语句那样,闪回表可以闪回表在某一时间点的状态来完全取代现在的这张表。如下面语句将表闪回到SCN2202666520的状态下:

SQL> FLASHBACK TABLE RECYCLETEST TO SCN 2202666520;

 

 

Top

Copyright ©2005,HelloDBA.Com 保留一切权利

申明
by fuyuncat