说说Flashback Drop Table缺陷

来源:互联网 发布:淘宝创业项目 编辑:程序博客网 时间:2024/05/21 01:31

10g开始,Oracle推出了一系列的Flashback技术。

 

从效果上看,flashback为数据恢复提供了一种简易的方法。对一些简单的事务、DDL操作,我们都可以在不需要进行复杂数据还原技术就可以“找回”那些数据。从本质上看,flashback主要依赖的Oracle的一些传统核心技术,加以丰富变通。

 

Flashback Table Drop是针对数据表Drop DDL操作确立的。当一个数据表被drop掉,真实数据段(Data Segment)并没有立刻被回收,而是以系统回收站的方式保存在系统中。一旦用户需要进行flashback,就可以直接从这些段中进行恢复。

 

1、方便的Flashback Drop Table

 

我们在Oracle 10g上进行试验。

 

 

SQL> conn scott/tiger@otstest;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0

Connected as scott

 

SQL> select * from v$version;

BANNER

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

Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod

PL/SQL Release 10.2.0.1.0 - Production

CORE     10.2.0.1.0       Production

 

TNS for 32-bit Windows: Version 10.2.0.1.0 - Production

NLSRTL Version 10.2.0.1.0 – Production

 

 

我们创建数据表T。注意,我们除了数据表,还有设置上索引和非空约束等信息。

 

 

SQL> create table t (id number, name varchar2(10) not null);

Table created

 

SQL> create index idx_t_id on t(id);

Index created

 

 

此时,我们可以看到上述对象产生的段信息。

 

 

SQL> select segment_name, segment_type from user_segments;

 

SEGMENT_NAME         SEGMENT_TYPE

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

T                    TABLE

IDX_T_ID             INDEX

(篇幅原因,省略结果……)

 

9 rows selected

 

 

接下来,我们将数据删除drop掉,观察数据字典变化情况。

 

 

SQL> drop table t;

Table dropped

 

SQL> select segment_name, segment_type from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE

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

DEPT                           TABLE

PK_EMP                         INDEX

BIN$nP3Pq/nMRgm1UCh/FhtQuw==$0 TABLE

BIN$V4mYHdDaRYqZpATnzuPuKQ==$0 INDEX

MT                             TABLE

 

9 rows selected

 

 

数据表被删除后,出现两个奇怪名称的对象,一个是数据表,另一个是索引。Drop操作后,Oracle并没有直接将其删除,而是rename为隐藏对象。

 

此时,从视图user_recyclebin中,也可以看到对象。

 

 

SQL> col original_name for a20;

SQL> select object_name, original_name, operation, type from user_recyclebin;

 

OBJECT_NAME                    ORIGINAL_NAME        OPERATION TYPE

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

BIN$nP3Pq/nMRgm1UCh/FhtQuw==$0 T                    DROP      TABLE

BIN$V4mYHdDaRYqZpATnzuPuKQ==$0 IDX_T_ID             DROP      INDEX

 

 

下面,我们进行flashback操作。

 

 

SQL> flashback table t to before drop;

Done

 

SQL> select * from t;

 

        ID NAME

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

 

 

但是,从段视图中,我们可以看到一丝问题。数据表T内容和结构名称虽然恢复,但是索引并没有一并的恢复回来。

 

 

SQL> select segment_name, segment_type from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE

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

T                              TABLE

BIN$V4mYHdDaRYqZpATnzuPuKQ==$0 INDEX

MT                             TABLE

 

9 rows selected

 

 

2、更名的索引和约束

 

我们使用dbms_meta包,抽取出数据表T相关的所有DDL信息如下:

 

 

CREATE TABLE "SCOTT"."T"

   ( "ID" NUMBER,

       "NAME" VARCHAR2(10) NOT NULL ENABLE

   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

  TABLESPACE "USERS" ;

 

  CREATE INDEX "SCOTT"."BIN$V4mYHdDaRYqZpATnzuPuKQ==$0" ON "SCOTT"."T" ("ID")

  PCTFREE 10 INITRANS 2 MAXTRANS 255

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)

  TABLESPACE "USERS" ;

 

  ALTER TABLE "SCOTT"."T" MODIFY ("NAME" NOT NULL ENABLE);

 

 

另外,在pl/sql developer上抽取出元数据中,还包括:

 

 

alter table T

  add constraint BIN$/ti5UoSFR9CblKXzoJxPBQ==$0

  check ("NAME" IS NOT NULL);

 

 

这里说明,索引对象和约束等信息内容,并没有随着flashback操作而发生逆转。

 

 

SQL> select constraint_name, constraint_type, table_name from user_constraints where table_name='T';

 

CONSTRAINT_NAME                CONSTRAINT_TYPE TABLE_NAME

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

BIN$/ti5UoSFR9CblKXzoJxPBQ==$0 C               T

 

SQL> select index_name, index_type, table_name from user_indexes where table_name='T';

 

INDEX_NAME                     INDEX_TYPE                  TABLE_NAME

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

BIN$V4mYHdDaRYqZpATnzuPuKQ==$0 NORMAL                      T

 

 

从现象上看,虽然数据表被恢复,索引和约束被恢复,但是两者的名称并没有恢复到原来的状态。

 

那么,这已经与我们心中的flashback完全任意恢复有距离了。这是Oracle的Bug吗?在MOS上我们找到了下面的讨论片段。

 

 

[ID 272053.1]

Flashback table to before drop command results in lose of original name of associated indexes.

 

When we flashback a dropped table, all the indexes associated with the table are recalled back with system generated names.

The indexes retain the same name that they obtained when they were dropped.

 

To create a copy of the table as of a specific time [ID 271659.1]

Note:- For out of place creation of the table, you only get data back. Constraints, indexes, and so on are not restored. This could take significantly more time and space than Flashback Table.

However, Flashback Table only restores rows in blocks that were modified after the specified time, making it more efficient.

 

 

从上面的资料中,索引和约束在flashback drop之后,保留原有的系统生成名称是Oracle的已确定机制。换句话说,flashback drop技术的核心目标是将drop掉数据表的数据找回来,一些辅助信息可以留待之后进行处理。

 

3、系统名称修正

 

我们需要做的,就是将索引和约束信息的名称rename为原来的名称。

 

 

--尝试恢复

SQL> alter index "BIN$V4mYHdDaRYqZpATnzuPuKQ==$0" rename to idx_t_id;

 

Index altered

 

SQL> select index_name, index_type, table_name from user_indexes where table_name='T';

 

INDEX_NAME                     INDEX_TYPE                  TABLE_NAME

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

IDX_T_ID                       NORMAL                      T

 

 

4、结论

 

Oracle flashback drop技术是一次重要的创新。让我们可以避免复杂的数据恢复工作,以回收站的方式找回DDL操作之前的数据表信息。同时,我们也需要关注flashback drop不能实现的一些方面,这样在实际中才能做到游刃有余。

0 0
原创粉丝点击