声明:本篇思路和知识点源自eygle老师作品。
本篇是笔者《使用闪回拯救我们的数据》系列之二。在Oracle9i之后,数据库闪回技术逐渐成熟。到10g时,数据库闪回已经成为一套比较完整的数据恢复方案。
提到闪回flashback,要注意Oracle的闪回技术是由几个相对独立的技术实现的。
ü 数据库级别闪回:flashback database。将整个数据库快速恢复到一个时间点;
ü 数据表级别闪回:将数据表全部恢复到过去的一个时间点上,或者对已经删除掉的数据表恢复;
ü 行级别闪回:设置指定的时间点,可以查询到该时间点的特定数据行;
ü 事务闪回:可以将按照事务的单位,将数据库变更闪回;
我们已经在本系列的第一篇中,介绍过行级别的闪回,可以将制定时间的数据行导出。在本篇中,我们介绍一下数据表级别的闪回。
在实际开发和维护中,我们有时候会遇到把数据表drop掉的情况。过去这种情况,我们只能通过之前保留的备份,进行不完全的备份。这样的工作量很大也很麻烦。从Oracle10g起,引入了回收站的机制,将drop掉的数据表保存在回收站中。当发现误删除的时候,可以通过回收站回收数据表。
回收站机制类似于我们在Windows上的回收站。在windows中,当我们选择删除一个文件时,本质上并没有将文件从硬盘上删除,只是将文件以一种形式改名,这样就能从回收站中看到。
Oracle的回收站也是采用同样的原理。下面我们做一个简单的实验。
首先,确定系统参数。在Oracle10g中,有一个参数recyclebin,控制数据表回收站机制的启动和关闭。
//用sys帐号登录,确定recyclebin参数
SQL> conn sys/sys@orcl as sysdba;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as SYS
SQL> show parameter recyclebin;
NAME TYPE VALUE
------------------------------------ ----------- ------
recyclebin string on //当取值为on的时候,表示开启回收站功能;
SQL>
之后,我们以scott用户登录进去,演示删除一张数据表。
SQL> conn scott/tiger@orcl;
Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Connected as scott
//建立数据表
SQL> create table t as select * from all_objects;
Table created
SQL> select count(*) from t;
COUNT(*)
----------
40712
之后删除数据表。
SQL> drop table t;
Table dropped
SQL> select * from t;
select * from t
ORA-00942: 表或视图不存在
在sqlplus(注意:只能在sqlplus/sqlplusw中查看到)中,使用show recyclebin命令,可以看到当前回收站的情况信息。
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T BIN$jJvR2eVETmKH1JE6yBQ2og==$0 TABLE 2011-01-25:22:30:52
记录的内容显而易见,有一个对象原名为T,在回收站中的名称为“BIN$…”。原来的对象类型为数据表,是在XXX时间被删除。
如果这个时候确定说删除是一个错误,需要恢复,简单的使用flashback命令,就可以了。
//使用闪回命令,将数据表t闪回到删除之前的状态去
SQL> flashback table t to before drop;
闪回完成。
SQL> select count(*) from t;
COUNT(*)
----------
40712
//数据恢复
一个简单的命令,就可以挽回我们误操作的结果了。
那么,如果我们不需要这个对象了,需要完全的删除。我们需要怎么做呢?而且,在windows的回收站里,文件在清空回收站之前是还会占用硬盘空间的。Oracle的回收站里面既然保存数据,那么必然要消耗数据库空间。
我们可以使用purge命令,对回收站的信息进行清除。
SQL> drop table t;
表已删除。
SQL> purge table t; //清除表
表已清除。
SQL> show recyclebin;
SQL> flashback table t to before drop; //尝试闪回,失败
flashback table t to before drop
*
第 1 行出现错误:
ORA-38305: 对象不在回收站中
同时,purge命令还提供了不同的操作粒度,如下:
ü purge table ; 对指定的数据表进行清除purge;
ü purge tablespace ; 对指定的表空间回收站进行purge;
ü purge tablespace user ;对指定表空间回收站中指定用户schema对象进行purge操作;
那么,如果我们不想通过回收站进行删除操作,希望在drop数据表的时候完全删除,怎么做呢?
SQL> select count(*) from t;
COUNT(*)
----------
40712
SQL> drop table t purge; //使用purge关键字,相当是说“不希望转入回收站”
表已删除。
SQL> show recyclebin;
谈到drop一个数据表,就不能不说truncate table操作。truncate操作具有操作快的特点,那么truncate命令是否支持闪回呢?
SQL> select count(*) from t;
COUNT(*)
----------
40712
SQL> truncate table t; //截断数据表
表被截断。
SQL> show recyclebin;
SQL> flashback table t to before drop; //没有在回收站中,也就必然不能支持闪回了;
flashback table t to before drop
*
第 1 行出现错误:
ORA-38305: 对象不在回收站中
那么,flashback drop的原理是如何的呢?回收站机制是怎么进行操作的呢?