DROP PARTITION为什么不进回收站

前几天在给公司的员工讲一个案例的提到这个问题。
其实当时提到了这个特点,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 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没有直接释放表在表空间上的空间占用,而是将表简单的打了个标识,这样在正常查询数据字典时就不会看到这张被删除的表,而如果需要恢复这张表时,只需要将标识位改回来既可。
那么同样是修改数据字典,为什么不能将被删除的分区通过标识的方法放到回收站中呢,这是因为,对于表而言,删除操作是将一个整理完全删除。而对于分区的删除,是删除整体中的一个部分。对于删除这个动作其实并没有太大的影响,但是回收站的功能不是为了删除,而是为了可以快速的恢复。对表而言,直接恢复整体不存在任何的问题,即使同名对象存在,也只需改个名字既可。而对于删除分区的恢复而言,问题就不那么简单了。由于分区表并没有删除,因此这个表仍然可以继续进行操作,虽然某个分区被删除了,但是除非是范围分区中的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却一直没有实现,那么很可能实现这个功能并不像想象的那么简单。

This entry was posted in ORACLE and tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *