現象
最近oracle數據庫空間告警,對表空間使用情況進行查詢時,發現有表名類似于<code>BIN$UPoITd+QCAPgTCqElzEbhg==$0</code>的表,這種類型的表是如何來的?能否進行刪除?
講知識
執行<code>DROP TABLE tableA</code>后會產生類似于<code>BIN$UPoITd+QCAPgTCqElzEbhg==$0</code>的文件名,這部分已刪除的文件是能夠繼續進行刪除的。
已刪除的文件為何會成為<code>BIN$UPoITd+QCAPgTCqElzEbhg==$0</code>這樣的文件呢?是因為在現在用的ORACLE中,存在回收站(Recycle Bin)這個玩意。
回收站
回收站是Oracle10g開始引入的一個概念
- 表刪除后,該表所占用的空間不會立即清空,而是將表相關信息(不是表數據)存入到回收站中。
- 回收站不單獨劃分存儲區域,它以現有的表空間為基礎,存放已經drop的表的信息。
- 回收站的存在,有助于將誤drop的表進行閃回(Flash Back)回退恢復
- 如果想要完全drop掉表并釋放表占用空間,使用<code>DROP TABLE tableA purge</code>
- 如果表空間足夠,不使用purge進行DROP的表會一直存放在回收站中
- 當表空間緊張時,數據庫會按照先進先出原則,覆蓋回收站中數據,被覆蓋的數據無法通過回收站閃回
查看回收站狀態
回收站開啟/關閉
查看回收站狀態:VALUE為on表示開啟,off為關閉
SELECT * FROM V$PARAMETER WHERE NAME='recyclebin';
關閉回收站
ALTER SESSION SET RECYCLEBIN=OFF;
打開回收站
ALTER SESSION SET RECYCLEBIN =ON;
查看回收站中表信息
SELECT * FROM USER_RECYCLEBIN;
RECYCLEBIN NAME的命名規則為BIN$GUID$Version其中GUID為GlobalUID,是一個全局唯一、24個字符長的標識對象,它是ORACLE內部使用的標識。其中$version是ORACLE數據庫分配的版本號。
閃回DROP表數據
FLASHBACK TABLE tableA TO BEFORE DROP;
如果tableA刪除多次,使用只會閃回tableA最后一次刪除的數據(后進先出原則)。
若多次執行上述閃回命令,會報ORA-38312錯誤。ORA-38312錯誤原因在于已存在表名為tableA的表,解決該錯誤方案為:閃回時將表改名
FLASHBACK TABLE tableA TO BEFORE DROP RENAME TO tableA_2;
如果想要將多次刪除的表,其中某次的數據恢復,可以直接指定OBJECT_NAME進行閃回
FLASHBACK TABLE "BIN$UPoITd+QCAPgTCqElzEbhg==$0" TO BEFORE DROP;
清除回收站
可以通過<code>DROP TABLE tableA purge</code>直接刪除表,不進入回收站
對于已進入回收站的,可以通過表名或刪除后在回收站中OBJECT_NAME名字進行刪除
PURGE TABLE tableA;
PURGE TABLE "BIN$UPoITd+QCAPgTCqElzEbhg==$0";
執行上述命令會將表上所有相關對象,如索引、約束等全部刪除。
如果只想刪除索引而將表數據保留,則可以使用
PURGE INDEX idx_tableA;
也可以根據表空間名稱,將回收站中該表空間記錄刪除
PURGE TABLESPACE tableA_SPACE;
也可以在上述命令中再加以限定,根據表空間名稱與該表空間中用戶進行刪除
PURGE TABLESPACE tableA_SPACE USER userName;
要釋放當前用戶所有回收站中信息
PURGE RECYCLEBIN;
上述命令只清除當前用戶回收站信息,如果要將所有回收站清空,需要DBA權限執行以下命令
PURGE DBA_RECYCLEBIN;
重點
- 表的參考約束不會被恢復,指向該對象的外鍵約束需要重建
- 如果該DROP表所占空間已被覆蓋,則該表不可恢復
- 刪除表時,該表上的視圖也會被刪除,但由于視圖不會放到回收站中,在執行FLASHBACK時視圖不會恢復
- 對于回收站中表對象,只支持查詢,不支持其他DML、DDL操作