ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 利用闪回拯救我们的数据(四)

利用闪回拯救我们的数据(四)

原创 Linux操作系统 作者:realkid4 时间:2011-01-29 20:45:46 0 删除 编辑

闪回机制探讨

 

下面我们一起来详细研究下,drop闪回的原理。首先,我们构建一个适当的实验环境。

 

 

SQL> conn scott/tiger@orcl;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0

Connected as scott

 

SQL> col object_name format a25;

SQL> select object_name,object_id,object_type from user_objects;

 

OBJECT_NAME                OBJECT_ID OBJECT_TYPE

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

PK_DEPT                        51150 INDEX

……(篇幅原因,有删节)

PCK_MYTEST_WORK                52607 PACKAGE BODY

T                              53218 TABLE

SYS_C005520                    53186 INDEX

IND_T_TEST_NAME                53187 INDEX

T_TEST                         53185 TABLE

 

14 rows selected

 

 

实验环境下,我们存在对象表T,对象编号为53218。对应的段信息为:

 

SQL> select segment_name, segment_type, tablespace_name, bytes from user_segments where segment_name='T';

 

SEGMENT_NA SEGMENT_TYPE       TABLESPACE_NAME           BYTES

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

T          TABLE              USERS                     65536

 

 

下面,我们尝试删除数据表T。

 

SQL> drop table t;

Table dropped

 

SQL> select * from t;

select * from t

 

ORA-00942: 表或视图不存在

 

 

我们重新查找对象字段视图。

 

SQL> select object_name,object_id,object_type from user_objects;

 

OBJECT_NAME                OBJECT_ID OBJECT_TYPE

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

PK_DEPT                        51150 INDEX

DEPT                           51149 TABLE

EMP                            51151 TABLE

PK_EMP                         51152 INDEX

BONUS                          51153 TABLE

SALGRADE                       51154 TABLE

P_ACCA_LOG_USER_COUNT          52786 PROCEDURE

PCK_MYTEST_WORK                52606 PACKAGE

MY_SEQ                         52578 SEQUENCE

PCK_MYTEST_WORK                52607 PACKAGE BODY

SYS_C005520                    53186 INDEX

IND_T_TEST_NAME                53187 INDEX

T_TEST                         53185 TABLE

BIN$/hWq4qC8ScioKlJiEL1jA      53218 TABLE

w==$0                               

 

 

14 rows selected

 

 

该结果没有删节。首先,发现对象T的信息已经不存在了。其次,一个以BIN$开头的数据表对象出现在视图中,而且使用了object_id为53218,与之前T所占用的object_id相同。接着让我们查看段信息。

 

SQL> col segment_name format a30;

SQL> select segment_name, segment_type, tablespace_name, bytes from user_segments;

 

SEGMENT_NAME                   SEGMENT_TYPE       TABLESPACE_NAME         BYTES

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

IND_T_TEST_NAME                INDEX              USERS                 65536

SYS_C005520                    INDEX              USERS                 65536

T_TEST                         TABLE              USERS                 65536

BIN$/hWq4qC8ScioKlJiEL1jAw==$0 TABLE              USERS                 65536

SALGRADE                       TABLE              USERS                 65536

BONUS                          TABLE              USERS                 65536

EMP                            TABLE              USERS                 65536

PK_DEPT                        INDEX              USERS                 65536

DEPT                           TABLE              USERS                 65536

PK_EMP                         INDEX              USERS                 65536

 

10 rows selected

 

 

数据段segment代表了存储。在数据段中,我们已经找不到数据表T的信息了。而新添加的BIN$却还是占据了一个位置。

 

最后,我们检查数据表视图。

 

SQL> select table_name, tablespace_name from user_tables;

 

TABLE_NAME                     TABLESPACE_NAME

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

DEPT                           USERS

EMP                            USERS

BONUS                          USERS

SALGRADE                       USERS

T_TEST                         USERS

 

 

数据表T信息被删除了,同时那个BIN$对象并没有被识别为数据表。

 

那么,回收站视图的情况呢?

 

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

 

OBJECT_NAME               ORIGINAL_NAME          OPERATION TYPETS_NAME

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

BIN$/hWq4qC8ScioKlJiEL1jA T              DROP      TABLE  USERS

w==$0                                                                                          

 

 

user_recyclebin帮助我们揭示了BIN$对象的本来面目。这个对象是记录原数据库表T的信息。

 

到此处,我们的结论也就不难获得了。所谓的闪回drop,就是一种对象假删除技术。当系统参数recyclebin被设置为on的时候,Oracle是开启闪回drop功能的。

 

当对数据表使用drop的时候,Oracle并不是将对象直接删除,而是采用了对象改名。将删除的数据表进行改名(逻辑上),改为BIN$开头的一个编码。

 

这个编码占据了原有数据表的所有资源(包括对象信息和存储信息),但是不能算成为原对象的等价体。也就是说,如果我们直接操作这个修改名,系统会报错,因为Oracle不认为这个对象是一个数据表。数据表T的数据字典信息被删除,而改名的对象信息没有加入其中。

 

 

SQL> select * from BIN$/hWq4qC8ScioKlJiEL1jAw==$0;

 

select * from BIN$/hWq4qC8ScioKlJiEL1jAw==$0

 

ORA-00933: SQL 命令未正确结束

 

 

当我们进行flashback table XXX to before drop的时候,Oracle只是将原来的数据表T信息重新改回,原有空间和数据并没有改变。

 

 

那么,这部分被假删除的数据是不是要占用原有对象表空间呢?答案是肯定的。就如同Windows回收站在没有清空的情况下,是同样消耗资源一样。Oracle的回收站也有同样的特性。

 

 

当我们删除了一个对象,这个对象信息隐藏咋数据表空间中,对象是占用空间的。但是,这部分空间的消耗并不计入到表空间容量之中。当表空间分配不足的时候,这部分闪回所用的硬盘空间是可以自动的被回收。作为一般开发人员和管理人员,这部分的操作是Oracle自动完成,相当于透明的操作。

 

 

那么,有没有可能因为闪回drop表空间对象引起一些故障问题呢?我们说是可能的。笔者曾经读到过一篇博文,文章中阐述了这样的场景(这里对文章作者表示敬意):

 

数据库操作程序中,向一个数据表中插入大量的数据,之后报错:说用户没有drop对象权限。为什么进行的insert操作,而提示说没有drop权限呢?程序用户也的确是没有drop权限。

 

最后发现是表空间中,非recyclebin可用空间使用耗尽,需要回收recyclebin中的空间。在这个过程中,Oracle不是使用直接覆盖的方法,而是自动生成了drop语句命令(一种递归调用),删除那些BIN$对象。在这个过程中,使用到了用户的drop权限。

 

解决的方法也很简单:管理员直接purge空间既可以。

 

 

闪回与安全

 

看了闪回功能,对我们的drop命令也有了一层新的认识。那么,可能有些应用是需要绝对安全删除(如PCI中的一项要求!),不希望一些被drop掉的信息还保留在数据库中,存在不安全因素。

 

对这种情况,可以使用两种方法。一个是直接关闭recyclebin参数,设置为off。这样就关闭了闪回drop的特性了。也就不会出现安全问题。这种方法笔者认为很实用,因为在生产环境下,drop数据表的情况还是比较少的,特别是应用层面。

 

第二个方法就是加参数的drop语句。使用drop table XXX purge,就不会将数据表保存在回收站中了。

 

SQL> select count(*) from t;

 

  COUNT(*)

----------

         0

 

SQL> drop table t purge;

 

Table dropped

 

SQL> select count(*) from user_recyclebin;

 

  COUNT(*)

----------

         0

 

//对象没有经过回收站,直接被删除;

 

 

同时,下面两个命令比较有用。

 

ü        drop tablespace XXX including contents;删除表空间的时候,不使用回收站,并连带清除回收站;

ü        drop user XXX cascade;删除用户和对应用户对象的时候,不使用回收站并连带清除回收站;

 

 

 

闪回特性

 

在这个系列中,我们介绍了闪回技术中的最常用的两个分支:闪回查询和闪回drop。经过我们的分析和讨论,可以发现:闪回是一个目标,并不代表一种技术。闪回所提倡的是在我们在进行破坏性操作,并且已经在事务生效之后,希望回到原点的一种快速恢复。在闪回之前,我们可能只能依靠复杂的备份恢复过程来实现这个目标,而有了闪回,这个目标可以轻而易举的实现。

 

但是,有一点要注意:闪回几个分支,包括数据库闪回、闪回查询和闪回drop都是依靠不同的机制和原理。共同点是实现的目标相同。闪回查询是利用的undo机制,闪回drop是借用了重命名和空间自动回收。所以我们在理解这三个分支的时候,要建立相对独立的知识体系,不要彼此混淆。

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

请登录后发表评论 登录
全部评论
求道~

注册时间:2010-11-30

  • 博文量
    545
  • 访问量
    7676919