今天的日记解答下面几点疑问:
1.怎么查询回收站内容?
2.怎么用flashback闪回回收站内容?
3. system表空间到底有没有回收站?
4. 如果回收站有同名文件,闪回的时候先恢复谁?
5. 如果用purge/cascade命令删除objects,是否进入了回收站?
6. 如何清理回收站节省表空间?
首先我们要了解oracle回收站的本质,其实它不是真正的一个物理存在,他只是存在相应表空间结构下的一种逻辑概念。怎么说?譬如我删除了users tablespace上的一张表(没有用purge或者cascade的情况下),表并非真正就直接从数据库消失了。而是在修改了表名字继续存在users tablespace上。
来测试下:
首先,我们在example表空间创建一张名字为ttt的表,数据来源引用DBA_users;
SQL> create table ttt tablespace example as select * from dba_users;
Table created.
然后,我们删除这张表(没有用purge或者cascade的情况下)
SQL> drop table ttt;
Table dropped.
怎么去回收站查找到这张被正常删掉的表呢?
=下面代码很重要,直接进回收站找内容============
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
TTT BIN$jCyEhEmvLSrgUwEAAH/yaw==$0 TABLE 2019-06-26:05:21:53
这样我们查到了TTT这张表,并且它已经被改名字了,虽然名字有些乱码,删除日期也看到了。
请问,数据还能被查询到吗?答案是YES。
SQL> select username from “BIN$jCyEhEmvLSrgUwEAAH/yaw==$0”;
SYS
SYSTEM
TEST123
T54321
JOY1
HR
TEST11
TEST
USER1
T321
TEST88
然后我们可以继续闪回flashback这种表,闪回后测试发现回收站内容清空了。
SQL> flashback table ttt to before drop;
Flashback complete.
SQL> desc ttt;
Name Null? Type
USERNAME NOT NULL VARCHAR2(30)
USER_ID NOT NULL NUMBER
SQL> show recyclebin;
测试结果显示,表闪回后,回收站内容被清空了
接着我们用sys账户创建非指定表空间的一张表(sys默认所在表空间自然是system表空间了),接着删除它,然后看其回收站是否有内容。
SQL> create table bbb as select * from dba_users;
Table created.
SQL> select table_name,tablespace_name from dba_tables where table_name=‘BBB’;
TABLE_NAME TABLESPACE_NAME
BBB SYSTEM
SQL> create table bbb as select * from dba_users;
Table created.
SQL> select table_name,tablespace_name from dba_tables where table_name=‘BBB’;
TABLE_NAME TABLESPACE_NAME
BBB SYSTEM
SQL> flashback table BBB to before drop;
flashback table BBB to before drop
*
ERROR at line 1:
ORA-38305: object not in RECYCLE BIN
SQL> desc bbb;
ERROR:
ORA-04043: object bbb does not exist
回收站内容一片空白,闪回提示回收站没有这表,描述也检索不到它,证明了,system表空间是不存在回收站概念的,一旦对象建立在这上面,删除就是永久删除了,闪回不回来了,所以尽可能不要将对象创建在system表空间上。
接着我们再次测试把两个同名对象删入回收站,用闪回看它的机制是什么?
SQL> create table ddd tablespace example as select * from dba_users;
Table created.
SQL> drop table ddd;
Table dropped.
SQL> create table ddd tablespace example as select * from dba_tables;
Table created.
SQL> drop table ddd;
Table dropped.
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
DDD BIN$jCyEhEnCLSrgUwEAAH/yaw== 0 T A B L E 2019 − 06 − 26 : 05 : 50 : 54 D D D B I N 0 TABLE 2019-06-26:05:50:54 DDD BIN 0TABLE2019−06−26:05:50:54DDDBINjCyEhEm/LSrgUwEAAH/yaw==$0 TABLE 2019-06-26:05:50:25
好的,经过我们不懈努力的创建和删除,现在example表空间的回收站有两张同名表啦。
拭目以待,如果我们闪回的话,是哪张DDD表被闪回呢?
SQL> flashback table ddd to before drop;
Flashback complete.
SQL> desc ddd;
Name Null? Type
OWNER NOT NULL VARCHAR2(30)
TABLE_NAME NOT NULL
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
DDD BIN$jCyEhEm/LSrgUwEAAH/yaw==$0 TABLE 2019-06-26:05:50:25
结果很显然,2019-06-26:05:50:54的DDD被闪回了,而 2019-06-26:05:50:25的DDD乖乖还躺在回收站,记住回收站同名闪回遵循last in first out规则,越新鲜越闪回。
那么又有另一个问题,我还想继续闪回另外一个同名文件怎么办呢?
SQL> flashback table DDD to before drop rename to HHH;
Flashback complete.
SQL> SELECT COUNT(*) FROM HHH;
45
SQL> show recyclebin;
答案很简单,加个rename to table_name就可以了。
接下来我们测试drop purge/cascade
SQL> create user abc identified by abc123 default tablespace example;
User created.
SQL> grant dba to abc;
Grant succeeded.
SQL> create table sss tablespace example as select * from dba_users;
Table created.
SQL> drop table sss purge;
Table dropped.
SQL> show recyclebin;
SQL> conn / as sysdba
Connected.
SQL> drop user abc;
drop user abc
*
ERROR at line 1:
ORA-01922: CASCADE must be specified to drop ‘ABC’
SQL> drop user abc cascade;
drop user abc cascade;
User dropped.
SQL> show recyclebin;
SQL> show recyclebin;
SQL>
====答案来了,对objects用drop…purge命令时,是不会进入回收站的,而是永久性删除,对user用drop …cascade命令时,所有对象也都全部删除了。所以purge和cascade慎用 ====。
最后一个,如何彻底情况回收站垃圾。
简单一行语句:
简单一行语句:如果是dba_recyclebin是将所有用户的回收站对象清空。
SQL> purge recyclebin;
Recyclebin purged.
SQL> purge dba_recyclebin;
Recyclebin purged.