关于Oracle11g回收站(Recycle Bin)对象的进入与恢复实验

一、基本原理

windows桌面系统有个回收站,文件删除后通常放到回收站里,用户可以将回收站中的文件还原。

Oracle回收站的原理完全一样,只是实现的细节方面有些差异.另外回收站中只能回收表和相关的对象包括索引、约束、触发器、嵌套表、大的二进制对(LOB)段和LOB索引段.

二、回收站功能的开启和关闭

查看回收站功能是否开启(默认为开启)

SQL> show parameter recyclebin;

NAME                                 TYPE        VALUE

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

recyclebin                           string      on

 

开启命令:alter system set recyclebin=on deferred;

关闭命令:alter system set recyclebin=off deferred;

deferred参数,对当前已经连接的sesion没有影响,但新连接的session将受到影响.

三、回收站的实验准备

Flashback不支持sys用户,system表空间下面的对象,也不能从回收站里拿到。故使用sys或是system用户登录时,show recyclebin为空。

所以,为了实验,新创建表空间test_ts及用户test

create tablespace test_ts datafile '/u01/app/oracle/oradata/orcl/test_ts.dbf' size 10m;

create user test identified by test default tablespace test_ts quota unlimited on test_ts;

grant connect,resource to test;

四、回收站实验,可以恢复表及主键和唯一约束(恢复后名称有变化,需手工rename)

用户test登录,检查回收站表,建普通表test_tab;

通过查询user_recyclebin或recyclebin获取当前用户drop掉的对象,发现无内容。

create table test_tab(id number);

insert into test_tab values (1);

commit;

select * from test_tab;

drop table test_tab;

select OBJECT_NAME,ORIGINAL_NAME,TS_NAME,DROPTIME from recyclebin;

OBJECT_NAME                    ORIGINAL_NAME                    TS_NAME                        DROPTIME

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

BIN$dacz1p9VzWXgUKjABZavgg==$0 TEST_TAB                         TEST_TS                        2018-09-12:17:32:15

由此可知:用户的表test_tab被drop后,进入回收站后命名为'BIN$dacz1p9VzWXgUKjABZavgg==$0',原名称以ORIGINAL_NAME字段记录,表空间仍然使用原来的表空间TEST_TS.

创建新表test_tab,插入数据后,再次drop,如下:

create table test_tab(id number);

insert into test_tab values (2);

commit;

drop table test_tab;

SQL> select OBJECT_NAME,ORIGINAL_NAME,TS_NAME,DROPTIME from recyclebin;

OBJECT_NAME                    ORIGINAL_NAME                    TS_NAME                        DROPTIME

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

BIN$dapFp5Bb0ELgUKjABZa1kQ==$0 TEST_TAB                         TEST_TS                        2018-09-12:17:32:42

BIN$dacz1p9VzWXgUKjABZavgg==$0 TEST_TAB                         TEST_TS                        2018-09-12:17:32:15

由此可知:回收站可以保存原名称为TEST_TAB的多个同名对象,对应的OBJECT_NAME、删除日期(DROPTIME)不同。

由于启动闪回功能后,对象的删除为逻辑删除,本质上为修改名称。所以可以直接对上述回收站中的对象进行操作。

例如:

查看表结构:desc "BIN$dapFp5Bb0ELgUKjABZa1kQ==$0";

查看表的记录:select count(*) from "BIN$dapFp5Bb0ELgUKjABZa1kQ==$0";

越过回收站直接删除(相当于windows下的按shift+delete键删除文件):

drop table test_tab purge;

当然也可以清空回收站:

purge table "BIN$dapFp5Bb0ELgUKjABZa1kQ==$0"

purge user_recyclebin; 

purge recyclebin;

下面试验带有主键的表如何恢复

create table student(id number,name varchar(5));

alter table student add constraint STU_PK primary key (id);

insert into student values (2,'wb');

commit;

drop table student;

SQL> select OBJECT_NAME,ORIGINAL_NAME,TS_NAME,DROPTIME from recyclebin;

OBJECT_NAME                    ORIGINAL_NAME                    TS_NAME                        DROPTIME

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

BIN$dacz1p9YzWXgUKjABZavgg==$0 STUDENT                          TEST_TS                        2018-09-12:17:36:17

BIN$dacz1p9XzWXgUKjABZavgg==$0 STU_PK                           TEST_TS                        2018-09-12:17:36:17

BIN$dapFp5Bb0ELgUKjABZa1kQ==$0 TEST_TAB                         TEST_TS                        2018-09-12:17:32:42

BIN$dacz1p9VzWXgUKjABZavgg==$0 TEST_TAB                         TEST_TS                        2018-09-12:17:32:15

恢复被删除的表TEST_TAB,后进先出,即恢复最近删除的名,虽然回收站中有两张TEST_TAB表,当然可以指定时间恢复早期drop的表()

flashback table TEST_TAB to before drop;

如果闪回的表名与当前的表名相同,需要重命名才可以闪回:

Flashback table TEST_TAB to before drop rename to OLD_TEST_TAB;

也可以指定回收站的对象名称进行恢复:

flashback table “BIN$dacz1p9VzWXgUKjABZavgg==$0” to before drop;

恢复成功后,回收站中少了一条记录

SQL> select OBJECT_NAME,ORIGINAL_NAME,TS_NAME,DROPTIME from recyclebin;

OBJECT_NAME                    ORIGINAL_NAME                    TS_NAME                        DROPTIME

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

BIN$dacz1p9YzWXgUKjABZavgg==$0 STUDENT                          TEST_TS                        2018-09-12:17:36:17

BIN$dacz1p9XzWXgUKjABZavgg==$0 STU_PK                           TEST_TS                        2018-09-12:17:36:17

BIN$dacz1p9VzWXgUKjABZavgg==$0 TEST_TAB                         TEST_TS                        2018-09-12:17:32:15

可以恢复表STUDENT

SQL> flashback table STUDENT to before drop;

执行上述操作后,回收站中的表与主键约束都被恢复了

SQL> select OBJECT_NAME,ORIGINAL_NAME,TS_NAME,DROPTIME from recyclebin;

OBJECT_NAME                    ORIGINAL_NAME                    TS_NAME                        DROPTIME

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

BIN$dacz1p9VzWXgUKjABZavgg==$0 TEST_TAB                         TEST_TS                        2018-09-12:17:32:15

只不过查看表STUDENT时发现,主键和唯一约束名称为回收站中的名称,如下:

create unique index BIN$dacz1p9XzWXgUKjABZavgg==$0 on STUDENT (ID)

alter table STUDENT  add constraint BIN$dacz1p9WzWXgUKjABZavgg==$0 primary key (ID);

可以将唯一约束进行改名:

alter index "BIN$dacz1p9XzWXgUKjABZavgg==$0" rename to STU_PK;

alter table STUDENT  rename  constraint "BIN$dacz1p9WzWXgUKjABZavgg==$0" to STU_PK;

五、关于带约束和外键表的恢复

创建部门表dept和员工表emp

-- 创建部门表emp

create table DEPT

(

  DEPT_id   NUMBER(4) not null,

  DEPT_name VARCHAR2(30),

  manager_id      NUMBER(6),

  location_id     NUMBER(4)

);

alter table DEPT   add constraint DEPT_PK primary key (DEPT_ID);

insert into dept select * from DEPARTMENTS;

-创建员工表emp

create table EMP

(

  emp_id    NUMBER(6) ,

  first_name     VARCHAR2(20),

  last_name      VARCHAR2(25),

  email          VARCHAR2(25),

  phone_number   VARCHAR2(20),

  hire_date      DATE,

  job_id         VARCHAR2(10),

  salary         NUMBER(8,2),

  commission_pct NUMBER(2,2),

  manager_id     NUMBER(6),

  dept_id  NUMBER(4)

  );

--创建两个索引

create index EMPJOB_IX on emp (JOB_ID);

create index EMPMANAGER_IX on emp(MANAGER_ID)

--创建主键

alter table emp  add constraint EMPPK primary key (emp_ID);

--创建外键

alter table emp  add constraint EMPDEPT_FK foreign key (dept_ID) references DEPT (dept_ID);

--创建检查性约束

alter table emp  add constraint EMPSAL_MIN check (salary > 0);

insert into emp select * from employees;

3)下面实验表drop后,通过查询user_recyclebin或recyclebin获取当前用户drop掉的对象

drop table emp;

SQL> select OBJECT_NAME,ORIGINAL_NAME,TS_NAME,DROPTIME from recyclebin;

OBJECT_NAME                    ORIGINAL_NAME                    TS_NAME                        DROPTIME

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

BIN$daeCdRADvgfgUKjABZawMg==$0 EMP                              TEST_TS                        2018-09-12:18:33:24

BIN$daeCdRACvgfgUKjABZawMg==$0 EMPPK                            TEST_TS                        2018-09-12:18:33:24

BIN$daeCdRABvgfgUKjABZawMg==$0 EMPMANAGER_IX                    TEST_TS                        2018-09-12:18:33:24

BIN$daeCdRAAvgfgUKjABZawMg==$0 EMPJOB_IX                        TEST_TS                        2018-09-12:18:33:24

由此可见,进回收站的只有表和索引(包括主键自带的唯一性索引),外建不进回收站也不恢复,主键和检查性约束不进回收站,但却能跟随表对象恢复。

恢复表emp;

flashback table EMP to before drop;

查看恢复后的表时,发现

进回收站的只有表和索引(包括主键自带的唯一性索引),外建不进回收站也不恢复,主键和检查性约束不进回收站,但却能跟随表对象恢复。