前幾天在給公司的員工講一個案例的提到這個問題。
其實當時提到了這個特點,DROP TABLE會進入回收站,但是DROP PARTITION并不會,因此DROP PARTITION之后,數據無法簡單的回復,只能通過邏輯或物理備份的方式來進行數據的回復。
SQL> create table t_drop (id number);
Table created.
SQL> drop table t_drop;
Table dropped.
SQL> select object_name, original_name from recyclebin;
OBJECT_NAME ORIGINAL_NAME
------------------------------ --------------------------------
BIN$xJhZqpmfWZXgRDzZK0pZWw==$0 T_DROP
SQL> create table t_part_drop (id number) partition by range (id)
2 (partition p1 values less than (10),
3 partition p2 values less than (20),
4 partition p3 values less than (30),
5 partition pmax values less than (maxvalue));
Table created.
SQL> insert into t_part_drop tb select rownum from user_objects;
176 rows created.
SQL> commit;
Commit complete.
SQL> alter table t_part_drop drop partition p1;
Table altered.
SQL> select object_name, original_name from recyclebin;
OBJECT_NAME ORIGINAL_NAME
------------------------------ --------------------------------
BIN$xJhZqpmfWZXgRDzZK0pZWw==$0 T_DROP
本來只是普及一下這個常識,不過有人問我Oracle為什么沒有實現將刪除分區放在回收站中。這個問題問的很好,因為如果這個功能很容易實現,那么Oracle肯定早就實現了,而到了11.2中Oracle仍然沒有實現這個功能,那么一定說明這個功能不是無法實現,就是實現的困難太大。
回收站的實現并不復雜,當一張表被刪除的時候,Oracle沒有直接釋放表在表空間上的空間占用,而是將表簡單的打了個標識,這樣在正常查詢數據字典時就不會看到這張被刪除的表,而如果需要恢復這張表時,只需要將標識位改回來既可。
那么同樣是修改數據字典,為什么不能將被刪除的分區通過標識的方法放到回收站中呢,這是因為,對于表而言,刪除操作是將一個整理完全刪除。而對于分區的刪除,是刪除整體中的一個部分。對于刪除這個動作其實并沒有太大的影響,但是回收站的功能不是為了刪除,而是為了可以快速的恢復。對表而言,直接恢復整體不存在任何的問題,即使同名對象存在,也只需改個名字既可。而對于刪除分區的恢復而言, tb 問題就不那么簡單了。由于分區表并沒有刪除,因此這個表仍然可以繼續進行操作,雖然某個分區被刪除了,但是除非是范圍分區中的MAXVALUE分區和列表分區中的DEFAULT分區,否則再插入原分區對應的數據時,并不會報錯,而是會插入到其他分區中:
SQL> select * from t_part_drop partition (p2);
ID
----------
10
11
12
13
14
15
16
17
18
19
10 rows selected.
SQL> insert into t_part_drop values (5);
1 row created.
SQL> select * from t_part_drop partition (p2);
ID
----------
10
11
12
13
14
15
16
17
18
19
5
11 rows selected.
原表應該插入分區P1的數據,由于分區P1被刪除,因此現在滿足分區P2的條件,被插入到分區P2中,考慮這種情況下,如果直接恢復P1分區會怎樣。
顯然這不是一個簡單的數據字典的修改就能解決的問題,不但涉及到分區數據改變的問題,還必然會帶來全局和本地索引失效的問題,更重要的是,可能帶來主鍵沖突的情況。
這還只是分區表進行了DML的情況,如果刪除分區后,分區表又進行了DDL,比如新SPLIT了P1分區,那么刪除分區的恢復操作就更無法進行了。
如果一個功能覺得很簡單就可以實現,但是Oracle卻一直沒有實現,那么很可能實現這個功能并不像想象的那么簡單。