操作 Oracle 時,經常會刪除一個表,當刪除錯誤后,希望能夠恢復該表,有時也希望刪除表之后能夠立刻釋放表的空間。
通過 purge 的使用可以在 Oracle 中刪除表、恢復表和空間釋放。
drop table
當在 Oracle 中刪除(drop)一個表時,數據庫不會立刻釋放表的空間,而是重命名這個表然后將其放入回收站,可以通過以下方式查詢:
select object_name,
original_name
from user_recyclebin
where original_name = 'TEMP'
OBJECT_NAME ORIGINAL_NAME
-------------------------------------------------------
BIN$C1LT5U0DaV7gVAAhKENZ5A==$0 TEMP
- object_name:對象在回收站中的名稱;
- original_name:對象的原始名稱。
表放入回收站后,Oracle 不會將該表的空間給其它對象使用,表所占用的空間依然占用,除非用戶手工進行 Purge 或者因為存儲空間不夠而被數據庫清掉。如果你發現錯誤的刪除了表,可以通過 flashback table 將表恢復。
flashback table
可以使用 flashback table 恢復已刪除的表。
flashback table temp to before drop;
to before drop 表示恢復這個表及其所有依賴的對象。如果該表的名稱已經被其它表使用,那么執行 flashback table 該表時則會報錯:ORA-38312:original name is used by an existing object
, 這時,可以在執行 flashback table 時將表重命名:
flashback table temp to before drop rename to temp_old;
rename to 表示將該表恢復后重命名。如果該表已經被刪除了多次,那么使用 flashback table 恢復該表將默認恢復最后一次刪除的那個,如果想恢復之前的一個版本,需要在回收站中查詢該表:
select object_name,original_name,droptime from user_recyclebin where original_name = 'TEMP';
OBJECT_NAME ORIGINAL_NAME DROPTIME
------------------------------------------------------------------------
BIN$C1LT5U0FaV7gVAAhKENZ5A==$0 TEMP 2014-12-29:10:59:41
BIN$C1LT5U0HaV7gVAAhKENZ5A==$0 TEMP 2014-12-29:10:59:54
BIN$C1LT5U0GaV7gVAAhKENZ5A==$0 TEMP 2014-12-29:10:59:47
然后可以使用那個恢復並重命名的方式依次恢復每一個。
使用 flashback table 需要注意:
- 數據庫將從回收站恢復該表的所有索引,注意bitmap join Index不能恢復,因為該索引在表格刪除后不會被放入回收站中,所以不能恢復;
- 數據庫將恢復該表的trigger和constraint,除了指向其它表的完整性約束;
- 當刪除一個表格時,定義在該表格上的所有物化視圖日志也被刪除,但不會放入回收站中,因此,物化視圖日志不能隨着表格被恢復;
- 當刪除一個表格時,該表格相關的所有索引都將被放入回收站中,如果數據庫空間不足,數據庫將首先清除掉索引的空間,因此,在這種情況下,恢復表格將無法恢復所有的索引;
- 如果被刪除的表格已經被 purge 了,那么將無法恢復。
如果用戶在刪除一個表后不會再恢復它,可以考慮使用 purge 將其徹底清除掉。
purge
purge 可以將表徹底清除,並且釋放表所占用的空間。
purge table temp;
drop table table_name purge;
需要注意不能回滾一個 purge 操作,一旦對一個表執行了 purge 操作,該表將無法再恢復。
如果該表被刪除了多次,purge 操作將清除最早刪除的那個表,也可以清除整個回收站的內容:
purge recyclebin;
drop table ... purge
也可以將刪除表格和釋放空間一步完成,例如:
drop table table_name purge;
這種方式相當於先刪除表格 table_name,然后在對表格執行 purge 操作。
注意,在這種情況下,不能回滾一個帶上 purge 的 drop table 操作,也不能恢復一個使用 purge 刪除的表格。
測試
如果在存儲過程中,或者是其他代碼中使用了 drop 語句刪除大量表,容易在回收站中產生垃圾,DBA會投訴。
如果確定要 drop 表,則最好加上 purge,但是要慎用,因為無法回滾。
在命令窗口下執行:
SQL> show parameter recycle;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
buffer_pool_recycle string
db_recycle_cache_size big integer 0
recyclebin string OFF
SQL> purge recyclebin;
Done -- 清空回收站
SQL> show recyclebin;
-- 查詢
SQL> drop table dt;
-- 刪除表
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
dt BIN$2cOZCZj0Ry27btpd7ymTHg==$0 TABLE 2019-04-10:10:56:58
SQL> flashback table dt to before drop;
-- 回滾數據表
SQL> drop table dt purge;
-- 刪除表並清空回收站
SQL> show recyclebin; -- 為空
參考鏈接1:Oracle tips:drop table和purge
參考鏈接2:[ORACLE]刪除表的purge用法