ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 恢复用户错误—使用flashback drop和flashback query

恢复用户错误—使用flashback drop和flashback query

原创 Linux操作系统 作者:treesofthehill 时间:2012-05-16 09:29:02 0 删除 编辑

1           闪回与ACID

Flashback drop提供了一种能够倒退drop table命令影响的方法,但这种方法不能保证成功。

Flashback query提供了能够倒退DML的方法,但这种方法也不能保证成功。

不论DML还是DDL,我们都无法回滚已提交的事务。ACID测试不允许这样的操作。闪回操作依赖于构造倒退原有事务的另外一个事务。闪回操作依赖于对撤销段的使用,而不依赖于对重做日志文件(包括重做归档和在线重做日志)

2           Flashback drop

Flashback drop允许将先前删除的表正确地恢复至其被删除前的状态,同时还会恢复所有的索引以及触发器和授权。此外,唯一约束、主键约束与非空约束也将被恢复,但是外家约束无法被恢复。

2.1          flashback drop的实现

。在10g以前的oracle数据库版本,drop table是针对SYS模式中表关于此表信息的deletecommit,但已删除表的数据并不会真正从磁盘中被删除,但其所使用的空间将被标记为未用,因此能够被重用。恢复被删除的表的唯一方法是执行时间点恢复(不完全恢复),从而将数据库还原为删除操作前数据字典仍然知道该表时的一个版本。

。在10g版本中,drop table是指定的表被重命名,而不是被删除。Drop table其实现在内部被映射为rename命令。已drop的表所占用的空间可以被重用。

已删除的对象被放在回收站里。使用user_recyclebin数据字典,可以查看每个用户都具有一个回收站。使用dba_recyclebin视图,可以查看回收站的整体情况。

在表空间遇到空间不足的压力时,回收站对象所占用的空间会被自动重用。

手动使用PURGE命令可以真正地删除指定的对象。

2.2          使用flashback drop

1Flashback drop的基本用法:

sys@ORCL>create table drop_tab(d1 date)  tablespace users;

 

表已创建。

 

sys@ORCL>select * from drop_tab;

 

未选定行

 

sys@ORCL>insert into drop_tab values(sysdate);

 

已创建 1 行。

 

sys@ORCL>commit;

 

提交完成。

 

sys@ORCL>select * from drop_tab;

D1

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

2012-05-14 14:34:20

 

sys@ORCL>drop table drop_tab;

 

表已删除。

 

sys@ORCL>flashback table drop_tab to before drop;

 

闪回完成。

 

sys@ORCL>select * from drop_tab;

D1

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

2012-05-14 14:34:20

 

 

2 使用PURGE命令

 

sys@ORCL>select * from drop_tab;

D1

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

2012-05-14 14:34:20

 

sys@ORCL>drop table drop_tab purge;

 

表已删除。

 

sys@ORCL>select * from drop_tab;

select * from drop_tab

              *

1 行出现错误:

ORA-00942: 表或视图不存在

 

 

sys@ORCL>flashback table drop_tab to before drop;

flashback table drop_tab to before drop

*

1 行出现错误:

ORA-38305: 对象不在回收站中

 

3使用rename命令

 

sys@ORCL>select * from drop_tab;

D1

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

2012-05-14 15:06:01

 

sys@ORCL>drop table dtop_tab;

drop table dtop_tab

           *

1 行出现错误:

ORA-00942: 表或视图不存在

 

 

sys@ORCL>drop table drop_tab;

 

表已删除。

 

sys@ORCL>select * from drop_tab;

select * from drop_tab

              *

1 行出现错误:

ORA-00942: 表或视图不存在

 

 

sys@ORCL>flashback table drop_tab to before drop rename to drop_tab1;

 

闪回完成。

 

sys@ORCL>select * from drop_tab;

select * from drop_tab

              *

1 行出现错误:

ORA-00942: 表或视图不存在

 

 

sys@ORCL>select * from drop_tab1;

D1

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

2012-05-14 15:06:01

Flashback drop 不能恢复truncate命令。

Flashback drop 不能恢复由drop user xxx cascade命令删除的用户的任何表。因为不能存在进行连接的用户,所以对模式的删除意味着oracle无法维护该模式所属的任何对象。

Flashback table “BIN$dZCY2dNWSKKcJMHFxVmMGg==$0” to before drop; 可以恢复回收站中指定的需要恢复版本。

例子:

练习flashback drop

1 准备

 system@ORCL>create user dropper identified by a123;

 

用户已创建。

 

system@ORCL>grant connect,resource to dropper;

 

授权成功。

 

system@ORCL>conn dropper/a123

已连接。

dropper@ORCL>create table names (name varchar2(10));

 

表已创建。

 

dropper@ORCL>create index name_idx on names(name);

 

索引已创建。

 

dropper@ORCL>alter table names add (constraint name_u unique(name));

 

表已更改。

 

dropper@ORCL>insert into names values('john');

 

已创建 1 行。

 

dropper@ORCL>commit;

 

提交完成。

 

2确定指定模式中的内容

 

dropper@ORCL>select object_name, object_type from user_objects;

OBJECT_NAME                    OBJECT_TYPE

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

NAME_IDX                       INDEX

NAMES                          TABLE

 

dropper@ORCL>select constraint_name,constraint_type,table_name from user_constraints;

CONSTRAINT_NAME                C TABLE_NAME

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

NAME_U                         U NAMES

 

3 删除新创建的表并查询

 

dropper@ORCL>drop table names;

 

表已删除。

 

dropper@ORCL>select object_name, object_type from user_objects;

 

未选定行

 

dropper@ORCL>select constraint_name,constraint_type,table_name from user_constraints;

CONSTRAINT_NAME                C TABLE_NAME

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

BIN$TjHgoqEzQo+/cSCpOdBaHQ==$0 U BIN$uBz2X+9wRqOxEQl3GXc5AA==$0

 

4通过回收站查询

 

dropper@ORCL>select object_name,original_name,type from user_recyclebin;

OBJECT_NAME             ORIGINAL_NAME       TYPE

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

BIN$dZCY2dNWSKKcJMHFxVmMGg==$0 NAME_IDX       INDEX

BIN$uBz2X+9wRqOxEQl3GXc5AA==$0   NAMES         TABLE

 

dropper@ORCL>select * from "BIN$uBz2X+9wRqOxEQl3GXc5AA==$0";

NAME

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

john

 

dropper@ORCL>insert into "BIN$uBz2X+9wRqOxEQl3GXc5AA==$0" values('damir');

insert into "BIN$uBz2X+9wRqOxEQl3GXc5AA==$0" values('damir')

            *

1 行出现错误:

ORA-38301: 无法对回收站中的对象执行 DDL/DML

 

5执行闪回操作

 

dropper@ORCL>flashback table names to before drop;

 

闪回完成。

 

dropper@ORCL>select object_name, object_type from user_objects;

OBJECT_NAME                    OBJECT_TYPE

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

NAMES                          TABLE

BIN$dZCY2dNWSKKcJMHFxVmMGg==$0 INDEX

 

dropper@ORCL>select constraint_name,constraint_type,table_name from user_constra

ints;

CONSTRAINT_NAME                C TABLE_NAME

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

BIN$TjHgoqEzQo+/cSCpOdBaHQ==$0 U NAMES

 

6 对索引和约束重命名

 

dropper@ORCL>alter index "BIN$dZCY2dNWSKKcJMHFxVmMGg==$0" rename to name_idx;

 

索引已更改。

 

dropper@ORCL>alter table names rename constraint "BIN$TjHgoqEzQo+/cSCpOdBaHQ==$0" to name_u;

 

表已更改。

 

dropper@ORCL>select object_name, object_type from user_objects;

OBJECT_NAME                    OBJECT_TYPE

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

NAMES                          TABLE

NAME_IDX                       INDEX

 

dropper@ORCL>select constraint_name,constraint_type,table_name from user_constraints;

CONSTRAINT_NAME                C TABLE_NAME

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

NAME_U                         U NAMES

 

6 删除模式

 

dropper@ORCL>conn system/123

已连接。

system@ORCL>drop user dropper cascade;

 

用户已删除。

 

7 查询dba_recyclebin视图,确定用户dropper的所有对象都被删除。

 

system@ORCL>select count(*) from dba_recyclebin where wner='DROPPER';

  COUNT(*)

----------

         0

 

3           管理回收站(recyclebin)

回收站:指的是被删除对象所使用的存储空间。

3.1 查询回收站

每个用户都有自己的回收站,可以使用show recyclebin命令查看在自己模式下删除的表。

可以查看user_recyclebindba_recyclebin视图查看整体情况。

system@ORCL>select owner, original_name, type, droptime,can_undrop,space from dba_recyclebin;

OWNER  ORIGINAL_NAME  TYPE     DROPTIME            CAN      SPACE

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

SYS        INVOICES        TABLE  2012-04-13:18:04:31    YES          8

XDB  XDB$CHECKOUTS_VCRUID_IDX INDEX 2012-05-10:10:25:55  NO          8

其中can_undrop” YES”,表能被恢复;can_undrop” NO”,索引不能被恢复。

SPACE列则显示了被删除对象所占用的空间大小。

SYSTEM表空间中存储的表无法启用flashback drop,因为这些表会被立即彻底清除,所以他们不能使用如前所述进行恢复。

3.2 收回回收站的空间

如果数据文件启动了自动扩展属性,那么重写回收站的操作优于增加数据文件大小的操作。

使用了先进先出算法,来收回回收站的空间。

Drop table xxx purge –永久删除表,并不移动到回收站。

Purge table xxx –从回收站永久地删除指定的表

Purge index xxx --从回收站永久地删除指定的索引。

Purge tablespace xxx –-永久删除回收站中属于指定tablespace的所有对象。

Purge tablespace xxx user xxx ---永久删除回收站中属于指定tablespace,并且是指定user的所有对象。

Purge user_recyclebin ---永久删除回收站中属于指定user的所有对象。

Purge dba_recyclebin ---永久删除回收站中的所有对象。

4           Flashback query

4.1 基本的flashback query

基本的flashback query形式:可以查询数据库在早先时间点的状态。

Flashback query 的所有形式都取决于撤销数据,从而能够重构早先时间点的数据。

命令格式如下:

select ... as of ...

具体例子如下:

select * from regions as of timestamp to_timestamp('2012-04-12 16:51:55','yyyy-mm-dd hh24:mi:ss');

select * from regions as of timestamp to_timestamp('2012-04-12 16:51:55','yyyy-mm-dd hh24:mi:ss') minus select * from regions;

可以使用dbms_flashback程序包

execute dbms_flashback.enable_at_time(-to_timestamp('2012-04-12 16:51:55','yyyy-mm-dd hh24:mi:ss'));

execute dbms_flashback.disable

如果构造过时结果集所需的撤销数据不可用,就会出现ora-08180错误。

例子

john@ORCL>select * from john1;

    JOHNID

----------

       110

       111

       102

       103

       104

 

john@ORCL>select sysdate from dual;

SYSDATE

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

2012-05-15 09:09:44

 

john@ORCL>delete from john1 where johnid=103;

 

已删除 1 行。

john@ORCL>commit;

 

提交完成。

 

john@ORCL>select * from john1;

    JOHNID

----------

       110

       111

       102

       104

 

john@ORCL>select * from john1 as of timestamp to_timestamp('2012-05-15 09:09:44'

, 'yyyy-mm-dd hh24:mi:ss');

    JOHNID

----------

       110

       111

       102

       103

           104

john@ORCL>select * from john1 as of timestamp to_timestamp('2012-05-15 09:09:44'

, 'yyyy-mm-dd hh24:mi:ss') minus select * from john1;

    JOHNID

----------

       103

john@ORCL>execute dbms_flashback.enable_at_time(to_timestamp('2012-05-15 09:09:4

4','yyyy-mm-dd hh24:mi:ss'));

BEGIN dbms_flashback.enable_at_time(to_timestamp('2012-05-15 09:09:44','yyyy-mm-

dd hh24:mi:ss')); END;

 

      *

1 行出现错误:

ORA-06550: 1 , 7 :

PLS-00201: 必须声明标识符 'DBMS_FLASHBACK'

ORA-06550: 1 , 7 :

PL/SQL: Statement ignored ---没有给john grant execute to dbms_flashback

给用户john授予execute to dbms_flashback执行如下:

sys@ORCL>grant execute on dbms_flashback to john;

sys@ORCL>conn john/123

已连接。

john@ORCL>execute dbms_flashback.enable_at_time(to_timestamp('2012-05-15 09:09:4

4','yyyy-mm-dd hh24:mi:ss'));

 

PL/SQL 过程已成功完成。

 

john@ORCL>select * from john1;

    JOHNID

----------

       110

       111

       102

       103

       104

john@ORCL>execute dbms_flashback.disable;

 

PL/SQL 过程已成功完成。

 

john@ORCL>select * from john1;

    JOHNID

----------

       110

       111

       102

       104

启动flashback query的语法可以接受时间标志或SCN。如果使用scn,那么闪回的时间点是精确的;如果使用指定时间点,那么这个时间点就会被映射为一个精度为3sscn

4.2 flashback table query

启动flashback table query步骤

。启用表上的记录转移。

Alter table dept enable row movement;

。启用闪回

Flashback table dept to timestamp to_timestamp('2012-04-12 16:51:55','yyyy-mm-dd hh24:mi:ss');

表闪回任然失败的主要原因有以下:

。没有启用表上的记录转移,就会出现ora-08189错误。

。在删除和闪回操作之间某个键值被重用,就会违反主键约束。

。不存在足够的、返回指定时间所需的撤销信息,就会出现ora-08180错误。

。受闪回影响的任何记录被其他用户锁定,就会出现ora-00054错误。

。表定义在相关的闪回期间不能发生变化,如果执行了ddl操作,就会出现ora-01466错误。

。对sys模式中的表不能应用闪回。

如果闪回失败,那么闪回操作就会被取消:已成功的部分将回滚,指定的表将回到执行闪回命令前的状态。

如果要在执行闪回操作期间触发DML触发器,可以使用以下命令:

Flashback table empdept to scn 6539425 enable triggers

4.3 flashback versions query

Flashback versions query允许我们查看某条记录的所有已提交版本,包括针对每个版本的创建时间和结束时间的时间标记。

伪列:是oracle在内部为记录添加的列。

具体主要有以下:

Rowid:用于数据库中每条记录的独特标志符,并且在索引中被用为返回指定表的指标。

以下伪列与闪回有关:

Versions_startscn:通过insertupdate命令的指定版本是相应的scn

Versions_starttime:创建记录的指定版本时相应的时间标记。

Versions_endscn:记录的指定版本由于deleteupdate命令而过期时相应的scn

Versions_endtime:记录的指定版本过期时相应的时间标记。

Versions_xid:创建记录指定版本的事务的独特标识符。

Versions_operations:创建记录指定版本的事务所执行的操作。

john@ORCL>select johnid, versions_xid, versions_startscn,versions_endscn,version

s_operation from john1 versions between scn minvalue and maxvalue;

    JOHNID VERSIONS_XID     VERSIONS_STARTSCN VERSIONS_ENDSCN V

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

       254 04000C0096020000           2396681                 I

john@ORCL>select johnid, versions_xid, versions_startscn,versions_endscn,version

s_operation from john1 versions between timestamp systimestamp - 15/1440 and sys

timestamp;

    JOHNID VERSIONS_XID     VERSIONS_STARTSCN VERSIONS_ENDSCN V

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

       254

4.4 flashback transaction query

flashback table queryflashback versions query是针对一个对象的撤销数据;而flashback transaction query是针对事务的所有撤销数据。

使用flashback_transaction_query视图确定指定事务影响的记录。

sys@ORCL>select operation,undo_sql from flashback_transaction_query where xid=he

xtoraw('02002A007F030000');

OPERATION   UNDO_SQL

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

INSERT      delete from "JOHN"."JOHN1" where ROWID = 'AAALkRAAEAAAAAMAAB';

5           闪回与撤销数据

闪回的不同形式取决于撤销数据。闪回查询是否成功,取决于撤销数据是否仍然可以。

为了保证flashback query在给定的时间周期内始终成功,需要为撤销表空间设置retention guarantee属性,同时还要设置undo_retention实例参数。

如果撤销表空间的大小无法满足事务的负荷,数据库就可能会被挂起。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9537053/viewspace-729879/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-06-11

  • 博文量
    97
  • 访问量
    179905