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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。