加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

闪回删除(Flashback Drop)

发布时间:2020-12-15 17:53:56 所属栏目:百科 来源:网络整理
导读:Flashback Drop 允许您将之前删除的表(但不是截断的表)恢复到刚好删除它之前的状态,同时还会恢复所有索引以及任何触发器和权限。唯一的主键和非空约束也会被恢复,但不包括外键。 Flashback Drop 命令仅适用于表,但是也会恢复所有相关的对象 -- 外键约束

Flashback Drop 允许您将之前删除的表(但不是截断的表)恢复到刚好删除它之前的状态,同时还会恢复所有索引以及任何触发器和权限。唯一的主键和非空约束也会被恢复,但不包括外键。

Flashback Drop 命令仅适用于表,但是也会恢复所有相关的对象 -- 外键约束除外。

实现闪回删除

从 10g 版本的 Oracle Database 开始,DROP TABLE 命令的实现方式完全不一样。在这些版本的数据库中根本没有删除表,而只是重命名它们。

SYS@orcl11g> select file_id,block_id,bytes from dba_extents
  2  where owner='SCOTT' and segment_name='OLD_NAME';

   FILE_ID   BLOCK_ID	   BYTES
---------- ---------- ----------
	 4	  520	   65536

SYS@orcl11g> alter table scott.old_name rename to new_name;

Table altered.

SYS@orcl11g> select file_id,bytes from dba_extents
  2  where owner='SCOTT' and segment_name='NEW_NAME';

   FILE_ID   BLOCK_ID	   BYTES
---------- ---------- ----------
	 4	  520	   65536
可以看到一个表 OLD_NAME 占用了 65 KB 的空间,从 4 号文件的 520 号块开始。在把该表重命名为 NEW_NAME 后,存储空间完全相同 -- 因此表也是一样的。查询 DBA_OBJECTS.OBJECT_ID 视图将会看到表的对象号也没有变化。

已经在内部将 DROP TABLE 命令映射到 RENAME 命令,它将作用于表及其所有相关的索引、触发器和约束,但不包括外键约束(它将被删除)。

每个用户都有一个回收站,可以在 USER_RECYCLEBIN 数据字典视图中看到它,若要了解全局视图,可以查询 DBA_RECYCLEBIN。当表空间的空间不足时,可以自动重用回收站对象占用的空间(此后不能恢复对象),或者可以手动强制 Oralce 使用 PURGE 命令真正删除对象。

使用 Flashback Drop 不能保证成功执行,但是很可能会失效。越早执行该命令,成功的可能性就越大。

使用闪回删除

SQL> drop table <table_name> purge;

SQL> flashback table <table_name> to before drop rename to <new_name>;

第一条命令会真正删除表,PURGE 关键字指示 Oracle 恢复 DROP 的原始含义:删除到该表的所有引用并且永远无法恢复。

第二条命令将闪回该表并重新命名。这样做是有必要的,以防在删除和闪回期间创建了另一个与删除的表具有相同名称的表。注意,尽管在闪回期间可以对表重命名,但不能改变模式:所有闪回操作出现在对象所属的模式内。和表一同闪回的索引、触发器和约束都保持它们的回收站名称。如果希望恢复它们原先的名称,则可以在闪回操作后手动重命名。

第一:Flashback Drop 只能在执行 DROP 命令后恢复,而不能恢复 TRUNCATE 命令。

第二:如果删除了一个用户,如下这样:

SQL> drop user scott cascade;

使用闪回无法恢复任何 SCOTT 的表,将模式删除意味着 Oracle 根本无法维护对象(即使在回收站内),因为没有可供对象连接的用户。

SCOTT@orcl11g> create table drop_tab (c1 date);

Table created.

SCOTT@orcl11g> insert into drop_tab values(sysdate);

1 row created.

SCOTT@orcl11g> commit;

Commit complete.

SCOTT@orcl11g> drop table drop_tab;

Table dropped.

SCOTT@orcl11g> select * from drop_tab;
select * from drop_tab
              *
ERROR at line 1:
ORA-00942: table or view does not exist


SCOTT@orcl11g> flashback table drop_tab to before drop;

Flashback complete.

SCOTT@orcl11g> select * from drop_tab;

C1
---------
09-SEP-13

SCOTT@orcl11g>
如果删除了表,然后创建了具有相同名称的另一个表,并且随后删除了它,那么在回收站中将有两个表。它们具有不同的回收站名称,但是原始名称相同。默认情况下,Flashback Drop 命令总是恢复最新版本的表,但是,如果这不是您想要的版本,则可以指定您希望恢复的版本的回收站名称,而不是原始名称。

SCOTT@orcl11g> select * from drop_tab;

C1
---------
09-SEP-13

SCOTT@orcl11g> drop table drop_tab;

Table dropped.

SCOTT@orcl11g> create table drop_tab(c1 date);

Table created.

SCOTT@orcl11g> drop table drop_tab;

Table dropped.

SCOTT@orcl11g> show recyclebin;
ORIGINAL NAME	 RECYCLEBIN NAME		OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
DROP_TAB	 BIN$5fNxyfQPzGbgQKjACwDw9w==$0 TABLE	     2013-09-09:20:37:22
DROP_TAB	 BIN$5fNxyfQOzGbgQKjACwDw9w==$0 TABLE	     2013-09-09:20:36:53
SCOTT@orcl11g> flashback table drop_tab to before drop;

Flashback complete.

SCOTT@orcl11g> select * from drop_tab;

no rows selected

SCOTT@orcl11g> show recyclebin;
ORIGINAL NAME	 RECYCLEBIN NAME		OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
DROP_TAB	 BIN$5fNxyfQOzGbgQKjACwDw9w==$0 TABLE	     2013-09-09:20:36:53
SCOTT@orcl11g> drop table drop_tab;

Table dropped.

SCOTT@orcl11g> show recyclebin;
ORIGINAL NAME	 RECYCLEBIN NAME		OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
DROP_TAB	 BIN$5fNxyfQQzGbgQKjACwDw9w==$0 TABLE	     2013-09-09:20:38:59
DROP_TAB	 BIN$5fNxyfQOzGbgQKjACwDw9w==$0 TABLE	     2013-09-09:20:36:53

SCOTT@orcl11g> flashback table "BIN$5fNxyfQOzGbgQKjACwDw9w==$0" to before drop;

Flashback complete.

SCOTT@orcl11g> select * from drop_tab;

C1
---------
09-SEP-13

SCOTT@orcl11g>
通过 SQL*Plus 使用闪回删除

在本练习中创建一个新的模式并在该模式内创建一个表,然后使用 Flashback Drop 恢复它。

1. 作用用户 SYSTEM 使用 SQL*Plus 连接数据库。

2. 为此练习创建一个用户:

SYSTEM@orcl11g> create user dropper identified by dropper;

User created.

SYSTEM@orcl11g> grant create session,resource to dropper;

Grant succeeded.

SYSTEM@orcl11g> connect dropper/dropper;
Connected.
DROPPER@orcl11g>
3. 创建一个带有索引和约束的表,并插入一行:

DROPPER@orcl11g> create table names (name varchar2(10));

Table created.

DROPPER@orcl11g> create index name_idx on names(name);

Index created.

DROPPER@orcl11g> alter table names add (constraint name_u unique(name));

Table altered.

DROPPER@orcl11g> insert into names values ('WYM');

1 row created.

DROPPER@orcl11g> commit;

Commit complete.

DROPPER@orcl11g>
4. 确认模式的内容:

DROPPER@orcl11g> select object_name,object_type from user_objects;

OBJECT_NAME OBJECT_TYPE
----------- -----------
NAME_IDX    INDEX
NAMES	    TABLE

DROPPER@orcl11g> select constraint_name,constraint_type,table_name from user_constraints;

CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME
--------------- --------------- ----------
NAME_U		U		NAMES

DROPPER@orcl11g>
5. 删除该表

DROPPER@orcl11g> drop table names;

Table dropped.
6. 重新运行步骤 4 中的查询。注意,已从 USER_OBJECTS 中删除了对象,但是仍存在采用系统生成的名称的约束。

DROPPER@orcl11g> select object_name,object_type from user_objects;

no rows selected

DROPPER@orcl11g> select constraint_name,table_name from user_constraints;

CONSTRAINT_NAME 	       C TABLE_NAME
------------------------------ - ------------------------------
BIN$5fQXS9/CdYLgQKjACwD4iw==$0 U BIN$5fQXS9/EdYLgQKjACwD4iw==$0

DROPPER@orcl11g>
7. 查询回收站以查看原始的名称到回收站名称的映射:

DROPPER@orcl11g> select object_name,original_name,type from user_recyclebin;

OBJECT_NAME		       ORIGINAL_NAME			TYPE
------------------------------ -------------------------------- -----
BIN$5fQXS9/DdYLgQKjACwD4iw==$0 NAME_IDX 			INDEX
BIN$5fQXS9/EdYLgQKjACwD4iw==$0 NAMES				TABLE
注意,该视图并没有显示约束。

8. 可以查询回收站但是无法对它执行 DML,注意,必须将表名称包含在双引号内,以便允许 SQL*Plus 正确地解析非标准字符。

DROPPER@orcl11g> select * from tab;

TNAME			       TABTYPE	CLUSTERID
------------------------------ ------- ----------
BIN$5fQXS9/EdYLgQKjACwD4iw==$0 TABLE

DROPPER@orcl11g> select * from "BIN$5fQXS9/EdYLgQKjACwD4iw==$0";

NAME
----------
WYM

DROPPER@orcl11g> insert into "BIN$5fQXS9/EdYLgQKjACwD4iw==$0" values('KELLY');
insert into "BIN$5fQXS9/EdYLgQKjACwD4iw==$0" values('KELLY')
            *
ERROR at line 1:
ORA-38301: can not perform DDL/DML over objects in Recycle Bin


DROPPER@orcl11g>
9. 使用 Flashback Drop 恢复表:

DROPPER@orcl11g> flashback table names to before drop;

Flashback complete.

DROPPER@orcl11g>
10. 重新运行步骤 4 中的查询
DROPPER@orcl11g> select object_name,object_type from user_objects;

OBJECT_NAME		       OBJECT_TYPE
------------------------------ -------------------
BIN$5fQXS9/DdYLgQKjACwD4iw==$0 INDEX
NAMES			       TABLE

DROPPER@orcl11g> select constraint_name,table_name from user_constraints;

CONSTRAINT_NAME 	       C TABLE_NAME
------------------------------ - ------------------------------
BIN$5fQXS9/CdYLgQKjACwD4iw==$0 U NAMES

DROPPER@orcl11g>
注意,索引和约束已保留了它们的回收站名称。

11. 将索引和约束重命名回原来的名称:

DROPPER@orcl11g> alter index "BIN$5fQXS9/DdYLgQKjACwD4iw==$0" rename to name_idx;

Index altered.

DROPPER@orcl11g> alter table names rename constraint "BIN$5fQXS9/CdYLgQKjACwD4iw==$0" to name_u;

Table altered.
12. 通过重新运行步骤 10 中的查询来确认操作成功:

DROPPER@orcl11g> select object_name,object_type from user_objects;

OBJECT_NAME		       OBJECT_TYPE
------------------------------ -------------------
NAME_IDX		       INDEX
NAMES			       TABLE

DROPPER@orcl11g> select constraint_name,table_name from user_constraints;

CONSTRAINT_NAME 	       C TABLE_NAME
------------------------------ - ------------------------------
NAME_U			       U NAMES

DROPPER@orcl11g>
13. 作为用户 SYSTEM 连接数据库,并删除 DROPPER 模式:

DROPPER@orcl11g> connect system/oracle;
Connected.
SYSTEM@orcl11g> drop user dropper cascade;

User dropped.

SYSTEM@orcl11g>
14. 查询 DBA_RECYCLEBIN 视图来证实确实删除了用户 DROPPER 拥有的所有对象:

SYSTEM@orcl11g> select count(*) from dba_recyclebin where owner='DROPPER';

  COUNT(*)
----------
	 0

SYSTEM@orcl11g>
管理回收站

回收站是表示删除的对象使用的存储空间的一个术语。可以完全忽略回收站 -- 它的管理是自动的,无论是在删除对象时将它们转移到回收站,还是活动对象的表空间需要空间时,都将它们永久清除。

可以使用实例参数 RECYCLEBIN 禁用回收站,默认值是 ON,意味着所有模式都有一个回收站。该参数是动态的,可以为某个会话或整个系统将其设置为 OFF。

每个用户都有自己的回收站,并且总是在自己的模式下查看删除的表。

SCOTT@orcl11g> show recyclebin;
ORIGINAL NAME	 RECYCLEBIN NAME		OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
TEMP_DEPT	 BIN$5fWfujxpL+XgQKjACwAPeA==$0 TABLE	     2013-09-09:22:58:41
TEMP_EMP	 BIN$5fWfujxqL+XgQKjACwAPeA==$0 TABLE	     2013-09-09:22:58:46
SCOTT@orcl11g>
若要了解更详细的信息,查询数据字典视图 USER_RECYCLEBIN 或 DBA_RECYCLEBIN 来查看全局视图:

SYS@orcl11g> list
  1  select owner,type,droptime,can_undrop,space
  2* from dba_recyclebin
SYS@orcl11g> /

OWNER ORIGINAL_NAME TYPE  DROPTIME	      CAN      SPACE
----- ------------- ----- ------------------- --- ----------
SCOTT TEMP_DEPT     TABLE 2013-09-09:22:58:41 YES	   8
SCOTT TEMP_EMP	    TABLE 2013-09-09:22:58:46 YES	   8

SYS@orcl11g>
关键的列是 CAN_UNDROP。Oracle 并不负责保存删除的表或索引:Flashback Drop 完全是 Oracle 提供的一个便利功能,并不属于关系数据库标准。如果 Oracle 需要删除对象占用的空间以便为活动对象分配更多的空间,它可以重用该空间 -- 但是从那以后使用 Flashback Drop 将无法恢复删除的对象,并且将从视图中清除它。 SPACE 列(单位是数据文件块)显示删除的对象占用的空间量。

Flashback Drop 不适用于存储在 SYSTEM 表空间中的表:因为直接将表删掉并清除了。

如果在回收站中有许多删除的对象,Oracle 将会首先重写在回收站中留存时间最长的对象。这种先进先出(First In First Out,FIFO)算法假定最近删除的对象最有可能充当闪回的候选对象。

drop table <table_name> purge; -- 删除表并且不将它转移到回收站

purge table <table_name>; -- 从回收站中清除表。如果存在多个具有相同原始名称的对象,那么将清楚时间最久的对象。也可以通过指定回收站名称来避免这种混淆。

purge index <index_name>; -- 从回收站中清楚索引 -- 这里同样可以指定原始名称或回收站名称。

purge tablespace <tablespace_name>; -- 从表空间中清除所有删除的对象

purge tablespace <tablespace_name> user <user_name>; -- 从表空间中清除属于一个用户的所有删除的对象

purge user_racyclebin; -- 清除您删除的所有对象

purge dba_recyclebin; -- 清除所有删除的对象,但是执行它需要 DBA 权限。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读