头图

Oracle的闪回删除(Flashback Drop)实际上从Oracle数据库的回收站中将已删除的对象,恢复到删除之前的状态。

一、 闪回删除简介

回收站是所有被删除对象及其相依对象的逻辑存储容器,例如当一个表被删除时,该表及其依赖的对象并不会马上被数据库彻底删除,而是被保存到回收站中。使用闪回删除功能,可以撤消drop table语句产生的影响,而不需要借助于传统的时间点恢复。通过使用闪回删除可以直接从Oracle的回收站中将删除的表恢复到删除之前的状态。

视频讲解如下:
https://www.bilibili.com/video/BV11am8YJEMm/?aid=113469143650...

二、 【实战】操作Oracle数据库的回收站

在了解到了什么是Oracle数据库的回收站后,下面将通过一个具体是示例来演示如何操作Oracle数据库的回收站。
(1)使用数据库管理员登录数据库,并检查回收站功能是否开启。

SQL> conn / as sysdba
SQL> select value from v$parameter where name='recyclebin';

# 输出的信息如下:
VALUE
-------------
on

# 如果没有开启回收站的功能,可以通过下面的语句开启Oracle数据库的回收站:
SQL> alter system|session set recyclebin=on;

(2)切换到c##scott用户,并查询用户下的表。

SQL> conn c##scott/tiger
SQL> select * from tab;

# 输出的信息如下:
TNAME        TABTYPE        CLUSTERID
---------- -----------  ------
BONUS        TABLE
COMM        TABLE
DEPT        TABLE
EMP            TABLE
......

(3)删除员工表emp

SQL> drop table emp;

# 由于在默认情况下启用了Oracle的回收站,这里将会把表删除到回收站中。
# 如果在删除表的时候不经过回收站直接删除,可以使用下面的语句。

SQL> drop table emp purge;

(4)查看回收站。

SQL> show recyclebin;

# 输出的信息如下:
ORIGINAL NAME        RECYCLEBIN NAME                OBJECT TYPE        DROP TIME
--------------  ------------------------------ ------------ ---------------------
EMP                BIN$2wRA2DnkHfrgUwEAAH88+w==$0    TABLE        2025-03-25:12:18:22

# 清空Oracle数据库的回收站可以使用下面的语句:
SQL> purge recyclebin;

# 为了确保在回收站中的对象的名称都是唯一的,
# Oracle会对回收站中的对象进行重命名,重命名的格式如下:
# BIN$globalUID$version
# 其中,BIN表示Oracle数据库的回收站;
# globalUID是一个全局唯一的、24个字节的对象,
# 该对象与原对象名没有任何关系;version指数据库分配的版本号。

(5)由于员工表并没有真正被删除,查询员工表的数据。

SQL> select * from emp where deptno=10;

# 此时将输出下面的错误信息:
ERROR at line 1:
ORA-00942: table or view does not exist

# 尽管员工表并没有真正被删除,
# 但此时表名已经改为了BIN$2wRA2DnkHfrgUwEAAH88+w==$0。

(6)通过表在回收站中的名称查询数据。

SQL> select * from BIN$2wRA2DnkHfrgUwEAAH88+w==$0 where deptno=10;

# 此时将出现下面的错误信息。
ERROR at line 1:
ORA-00933: SQL command not properly ended

# 通过表在回收站中的名称查询原来表数据的时候,需要在表名上加上双引号。

(7)加上双引号,通过表在回收站中的名称查询数据。

SQL> select * from "BIN$2wRA2DnkHfrgUwEAAH88+w==$0" where deptno=10;;

# 输出的信息如下:
EMPNO    ENAME    JOB            MGR        HIREDATE    SAL        COMM    DEPTNO
------ ------- ----------- ------- ----------- ------- ------- ----------
7782    CLARK    MANAGER        7839    09-JUN-81    2450                10
7839    KING    PRESIDENT            17-NOV-81    5000                10
7934    MILLER    CLERK        7782    23-JAN-82    1300                10

# 值得注意的时,数据库管理员是没有回收站的。

(8)切换到数据库管理员上,并创建一张表。

SQL> conn / as sysdba
SQL> create table testtable as select * from c##scott.dept;

(9)查询表testtable中的数据。

SQL> select * from testtable;

# 输出的信息如下:
DEPTNO        DNAME            LOC
---------- -------------- -----------
    10        DName123        NEW YORK
    20        RESEARCH        DALLAS
    30        SALES            CHICAGO
    40        OPERATIONS        BOSTON

(10)删除表testtable。

SQL> drop table testtable;

# 由于在使用drop table语句时并没有使用参数purge,
# 表testtable应该是被删除到Oracle的回收站中。
# 但是由于当前用户是管理员用户,他是没有回收站的。
# 因此表testtable将直接被删除。换句话说,回收站只针对普通用户有效。

(11)查看回收站。

SQL> show recyclebin;

# 此时回收站中没有任何的记录。

三、 【实战】使用闪回删除从回收站中恢复数据

在了解到了什么是Oracle数据库的回收站后,下面将通过一个具体是示例来演示如何使用闪回删除从回收站中恢复表。这里以之前删除的员工表emp为例来进行演示。
(1)切换到c##scott用户,并且查看回收站中的信息。

SQL> conn c##scott/tiger
SQL> show recyclebin;

# 输出的信息如下:
ORIGINAL NAME    RECYCLEBIN NAME                    OBJECT TYPE        DROP TIME
-------------- -------------------------------  ------------ -----------------------
EMP                BIN$2wRA2DnkHfrgUwEAAH88+w==$0    TABLE            2025-03-25:12:18:22

(2)执行闪回删除恢复表。

SQL> flashback table emp to before drop;

# 此处也可以使用表在回收站中的名称执行闪回删除,
# 但需要在名称上加上双引号。例如:
SQL> flashback table "BIN$2wRA2DnkHfrgUwEAAH88+w==$0" to before drop;

(3)验证员工表及数据是否恢复。

SQL> select * from emp where deptno=10;

# 输出的信息如下:
EMPNO    ENAME    JOB            MGR        HIREDATE    SAL        COMM    DEPTNO
------ ------- ----------- ------- ----------- ------- ------- ----------
7782    CLARK    MANAGER        7839    09-JUN-81    2450                10
7839    KING    PRESIDENT            17-NOV-81    5000                10
7934    MILLER    CLERK        7782    23-JAN-82    1300                10

(4)再次删除员工表

SQL> drop table emp;

(5)重新创建一张新的表。表名也叫emp,并往新表中插入一些数据。

SQL> create table emp(tid number);
SQL> insert into emp values(1);
SQL> commit;

(6)删除新建的emp表。

SQL> drop table emp;

(7)查看回收站中的信息。

SQL> show recyclebin;

# 输出的信息如下:
ORIGINAL NAME    RECYCLEBIN NAME                    OBJECT TYPE        DROP TIME
--------------- ------------------------------- ------------ ------------------------
EMP                BIN$2wVIwwEZItLgUwEAAH/P1A==$0    TABLE            2025-03-25:13:32:40
EMP                BIN$2wVIwwEYItLgUwEAAH/P1A==$0    TABLE            2025-03-25:13:32:10

# 此时回收站中的ORIGINAL NAME就有两张重名的表,
# 但RECYCLEBIN NAME是不重复的。
# 如果通过RECYCLEBIN NAME执行闪回删除操作,将不会产生歧义。

(8)执行闪回删除从回收站中恢复表。

SQL> flashback table emp to before drop;

(9)查看恢复的表结构。

SQL> desc emp;

# 输出的信息如下:
 Name     Null?      Type
 ---------- --------------- --------
 TID     NUMBER

# 从这里可以看出,如果回收站中存在ORIGINAL NAME重名的表,
# 先闪回后删除的表。此时回收站中还存在一张名叫emp的表。

(10)再次执行闪回删除从回收站中恢复表。

SQL> flashback table emp to before drop;

# 将输出下面的错误信息:
ERROR at line 1:
ORA-38312: original name is used by an existing object

# 由于当前用户下已经有一张名叫emp的表,
# 因此再次闪回同名表时就需要修改一下表的名称。

(11)重新执行闪回表的操作,并指定闪回成功后的表名。

SQL> flashback table emp to before drop rename to empold;

(12)查看表empold中的数据。

SQL> select * from empold where deptno=10;

# 输出的信息如下:
EMPNO    ENAME    JOB            MGR        HIREDATE    SAL        COMM    DEPTNO
------ ------- ----------- ------- ----------- ------- ------- ----------
7782    CLARK    MANAGER        7839    09-JUN-81    2450                10
7839    KING    PRESIDENT            17-NOV-81    5000                10
7934    MILLER    CLERK        7782    23-JAN-82    1300                10

赵渝强老师
36 声望15 粉丝

20年以上的IT行业从业经历,清华大学计算机软件工程专业毕业,京东大学大数据学院院长,Oracle中国有限公司高级技术顾问;曾在BEA、甲骨文、摩托罗拉等世界500强公司担任高级软件架构师或咨询顾问等要职,精通大...