什么是回收站?
回收站实际上是一个包含已删除对象的数据字典表。包括已删除的表和关联的如索引、约束等实体未被移除继续占用空间的对象。这部分对象继续占用用户的分配空间配额,直到表空间的容量不足时才会被重新使用。说的有点绕,Oracle的回收站和操作系统的回收站很像。
每个用户都有自己的回收站,除了sysdba权限的外的用户仅能访问自己的回收站。查看方法如下:
SCOTT@PROD> select * from recyclebin;no rows selected
看到回收站没有记录,下面我们创建一个表,并删除它,再查看回收站的情况:
SCOTT@PROD> create table deptbak as select * from dept;Table created.SCOTT@PROD> drop table deptbak;Table dropped.SQL> select * from recyclebin;OBJECT_NAME ORIGINAL_NAME OPERATION TYPE TS_NAME CREATETIME DROPTIME DROPSCN PARTITION_NAME CAN_UNDROP CAN_PURGE RELATED BASE_OBJECT PURGE_OBJECT SPACE------------------------------ -------------------------------- --------- ------------------------- ------------------------------ ------------------- ------------------- ---------- -------------------------------- ---------- --------- ---------- ----------- ------------ ----------BIN$i/U9xzbGCgzgU3s4qMDx+w==$0 DEPTBAK DROP TABLE USERS 2019-06-23:10:11:13 2019-06-23:10:13:28 971033 YES YES 87799 87799 87799 8
哇好多的字段啊,别害怕,有没有简短点的,sqlplus里可以使用show recyclebin命令查看回收站
SCOTT@PROD> show recyclebin;ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME---------------- ------------------------------ ------------ -------------------DEPTBAK BIN$i/U9xzbGCgzgU3s4qMDx+w==$0 TABLE 2019-06-23:10:13:28
关键的字段出来了,其中original name是对象的原始名字,不可使用了,recyclebin name是回收站内的名字,也是实体的真实名字,注意看这个名字命名规则Bin$随机串$版本,
既然看到了回收站里有东西,接下来我们有三种做法
1)继续放着,等着系统自己回收
2)主动清理掉,因为我是洁癖
3)误删除,我反悔了。
情况1就当我没说。
下面说说情况2如何处理。
其实很简单,使用清理语句 purge table "回收站名称";就可以清理掉了,如下:
SCOTT@PROD> purge table "BIN$i/U9xzbGCgzgU3s4qMDx+w==$0";Table purged.
这样就清理掉了一个表和其关联的索引、约束等对象。
问题来了,如何直接删除掉一个表呢?能不能不进回收站,直接清理,两种方法
1)drop … purge
2)关闭回收站
先来看第一种情况
SCOTT@PROD> create table deptbak as select * from dept;Table created.SCOTT@PROD> drop table deptbak purge;Table dropped.SCOTT@PROD> show recyclebin;SCOTT@PROD>
这种删除表的方法,就不会进回收站了。
第二种方法关闭回收站也有两种方法,一个是临时关闭也就是session(会话),一个是系统级别的,系统级别需要sys用户才能关,而且需要重启数据库。我们来看会话级别的:
SCOTT@PROD> alter session set recyclebin=OFF;Session altered.
这个时候再来看看删除表的情况如何:
SCOTT@PROD> create table deptbak as select * from dept;Table created.SCOTT@PROD> drop table deptbak;Table dropped.SCOTT@PROD> show recyclebin;SCOTT@PROD>
是的回收站内是空的了。
关闭整个系统的回收站功能类似,但是不建议启用。
最关键的步骤3,恢复删除掉的表
这个需要flashback(闪回,闪现随你喜欢的名字) 操作,
SCOTT@PROD> create table deptbak as select * from dept;Table created.SCOTT@PROD> drop table deptbak;Table dropped.SCOTT@PROD> show recyclebin;ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME---------------- ------------------------------ ------------ -------------------DEPTBAK BIN$i/W51fA7CungU3s4qMCoAA==$0 TABLE 2019-06-23:10:48:09SCOTT@PROD> flashback table DEPTBAK to before drop;Flashback complete.SCOTT@PROD> show recyclebin;SCOTT@PROD> select count(*) cou from deptbak;COU----------4
恢复后,回收站内的相应信息消失。
再来讨论一种情况,我删除了一个表,deptbak,然后我又创建了一个表,名字还叫deptbak,这个时候怎么恢复呢?涉及到同名的问题,牛逼闪闪的oracle注意到了你这个恶心操作,具体看下面:
SCOTT@PROD> create table deptbak as select * from dept;Table created.SCOTT@PROD> drop table deptbak;Table dropped.SCOTT@PROD> create table deptbak (id int,name varchar2(10));Table created.SCOTT@PROD> show recyclebin;ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME---------------- ------------------------------ ------------ -------------------DEPTBAK BIN$i/W51fA8CungU3s4qMCoAA==$0 TABLE 2019-06-23:11:02:21
这时候再用之前的语句回复会怎么样呢?
SCOTT@PROD> flashback table "BIN$i/W51fA8CungU3s4qMCoAA==$0" to before drop;flashback table "BIN$i/W51fA8CungU3s4qMCoAA==$0" to before drop*ERROR at line 1:ORA-38312: original name is used by an existing object
原始文件名已经存在了,那怎么办?改名呗:
SCOTT@PROD> flashback table "BIN$i/W51fA8CungU3s4qMCoAA==$0" to before drop rename to DEPTBAK_BIN;Flashback complete.SCOTT@PROD> select count(*) cou from deptbak_bin;COU----------4
神奇的deptbak换了个马甲又回来了。那么问题又来了,索引和约束这些辅助虽然也会恢复,但是需要改名,要不然给你恢复的名字,亲妈都不认识。看下面的例子
SCOTT@PROD> create table deptbak as select * from dept;SCOTT@PROD> create index deptbak_deptno on deptbak(deptno);SCOTT@PROD> drop table deptbak;SCOTT@PROD> show recyclebin;ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME---------------- ------------------------------ ------------ -------------------DEPTBAK BIN$i/W51fA+CungU3s4qMCoAA==$0 TABLE 2019-06-23:11:14:32SCOTT@PROD> select index_name from user_indexes where table_name='DEPTBAK';no rows selected
注意索引已经被株连删除了,下面闪回deptbak
SCOTT@PROD> flashback table "BIN$i/W51fA+CungU3s4qMCoAA==$0" to before drop;Flashback complete.SCOTT@PROD> select table_name from user_tables where table_name='DEPTBAK';TABLE_NAME------------------------------DEPTBAK
表是回来了,下面看索引啥情况了
SCOTT@PROD> select index_name from user_indexes where table_name='DEPTBAK';INDEX_NAME------------------------------BIN$i/W51fA9CungU3s4qMCoAA==$0
闪回来的索引名字,血缘关系还在,但是名字真的是亲妈不认识,怎么办?改名呗
SCOTT@PROD> alter index "BIN$i/W51fA9CungU3s4qMCoAA==$0" rename to deptbak_deptno;Index altered.SCOTT@PROD> select index_name from user_indexes where table_name='DEPTBAK';INDEX_NAME------------------------------DEPTBAK_DEPTNO
索引也名正言顺了,有人说,删除重建不行吗,可以,随你喜欢,不过大索引删除、重建的成本比较高,毕竟都是纯纯的磁盘IO操作啊。约束的处理办法参考索引的办法。
临了一句话,注意操作中的有使用双引号的地方,必须用,否则,嘿嘿,我就在后面告诉你,谁让你自作主张不老老实实的写呢。
综上就是Oracle中的回收站recycle bin的相关情况,为啥要写这个东西,因为给你一个月光宝盒啊!这是闪回的一种,连结构和数据都闪回了,后续的啃食文章还会写其它关于闪回方面的炫目操作!
喜欢就关注我,读到这你还不点个赞?给点动力写下去啊!