【发布时间】:2010-11-26 14:14:01
【问题描述】:
我在我的一张表中使用了 11g 间隔分区功能。我将其设置为在时间戳字段上创建 1 天分区,并创建一个作业来删除 3 个月前的数据。当我尝试删除最旧的分区时,出现以下错误:
ORA-14758: 无法删除范围部分中的最后一个分区
我会认为“最后一个”是指最新的分区而不是最旧的分区。我应该如何解释这个错误?我的分区有问题吗,还是我应该一直保留最旧的分区?
【问题讨论】:
我在我的一张表中使用了 11g 间隔分区功能。我将其设置为在时间戳字段上创建 1 天分区,并创建一个作业来删除 3 个月前的数据。当我尝试删除最旧的分区时,出现以下错误:
ORA-14758: 无法删除范围部分中的最后一个分区
我会认为“最后一个”是指最新的分区而不是最旧的分区。我应该如何解释这个错误?我的分区有问题吗,还是我应该一直保留最旧的分区?
【问题讨论】:
是的,错误消息有些误导,但它指的是最后一个静态创建的分区(在 Oracle 开始自动创建分区之前在原始表 DDL 中。我认为避免这种情况的唯一方法是创建一个人为的“MINVAL " 您确定永远不会使用的分区,然后将实际分区放在此分区之上。
[交换cmets后编辑]
我假设这个测试用例重现了你的问题:
CREATE TABLE test
( t_time DATE
)
PARTITION BY RANGE (t_time)
INTERVAL(NUMTODSINTERVAL(1, 'DAY'))
( PARTITION p0 VALUES LESS THAN (TO_DATE('09-1-2009', 'MM-DD-YYYY')),
PARTITION p1 VALUES LESS THAN (TO_DATE('09-2-2009', 'MM-DD-YYYY')),
PARTITION p2 VALUES LESS THAN (TO_DATE('09-3-2009', 'MM-DD-YYYY')),
PARTITION p3 VALUES LESS THAN (TO_DATE('09-4-2009', 'MM-DD-YYYY'))
);
insert into test values(TO_DATE('08-29-2009', 'MM-DD-YYYY'));
insert into test values(TO_DATE('09-1-2009', 'MM-DD-YYYY'));
insert into test values(TO_DATE('09-3-2009', 'MM-DD-YYYY'));
insert into test values(TO_DATE('09-10-2009', 'MM-DD-YYYY'));
当我这样做时,我可以删除分区 p0、p1 和 p2,但在尝试删除 p3 时会出现错误,即使除此之外还有系统生成的分区。
我能找到的唯一解决方法是通过以下方式临时重新定义表分区:
alter table test set interval ();
然后删除分区 p3。然后您可以通过以下方式按照原始规范重新定义分区:
alter table test set INTERVAL(NUMTODSINTERVAL(1, 'DAY'));
【讨论】:
dpbradley 的回答全部正确。但是,如果您要删除最旧的分区,则可以采取更安全的方式:
事实上,像这样重置间隔就足够了:
alter table test set interval ();
alter table test set INTERVAL(NUMTODSINTERVAL(1, 'DAY'));
然后删除分区最旧的分区。
否则如果删除分区失败则存在风险,那么表将没有间隔。所以需要捕获所有异常并处理它。
【讨论】: