【问题标题】:Unable to delete oldest table partition无法删除最旧的表分区
【发布时间】:2010-11-26 14:14:01
【问题描述】:

我在我的一张表中使用了 11g 间隔分区功能。我将其设置为在时间戳字段上创建 1 天分区,并创建一个作业来删除 3 个月前的数据。当我尝试删除最旧的分区时,出现以下错误:

ORA-14758: 无法删除范围部分中的最后一个分区

我会认为“最后一个”是指最新的分区而不是最旧的分区。我应该如何解释这个错误?我的分区有问题吗,还是我应该一直保留最旧的分区?

【问题讨论】:

    标签: oracle11g partitioning


    【解决方案1】:

    是的,错误消息有些误导,但它指的是最后一个静态创建的分区(在 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'));
    

    【讨论】:

    • 通过分区的名称,我可以看出这是自动创建的,最奇怪的是我能够删除在该分区之前静态创建的分区。无论如何我想试试你的建议,我得到了这个错误:alter table TABLE1 add partition test VALUES LESS THAN ('07-JUL-09 11.59.00.000000000 PM');第 1 行的错误:ORA-14760:在间隔分区对象上不允许添加分区有什么想法吗?谢谢,PJ
    • 嗯...我遇到了您的问题,就我而言,这是静态与动态定位问题。当我提到 MINVAL 分区时,我正在考虑使用这个单一分区(并定义了间隔分区)重新创建表,然后重新插入数据 - 在您的情况下这可能吗?
    • 我没有足够的磁盘空间,这个表很大。这实际上可能是第一个自动创建的分区。我可以删除较新的分区...您能想到其他解决方法吗?
    • 我还没有尝试过这种跨越分区类型的方式,但是您可以执行 SPLIT 或 MERGE 分区操作来移动边界吗?
    • 回复我自己的评论 - SPLIT/MERGE 没有帮助 - 用我能想到的唯一解决方案编辑了我的答案。
    【解决方案2】:

    dpbradley 的回答全部正确。但是,如果您要删除最旧的分区,则可以采取更安全的方式:

    事实上,像这样重置间隔就足够了:

    alter table test set interval ();
    alter table test set INTERVAL(NUMTODSINTERVAL(1, 'DAY'));
    

    然后删除分区最旧的分区。

    否则如果删除分区失败则存在风险,那么表将没有间隔。所以需要捕获所有异常并处理它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-25
      • 1970-01-01
      • 2018-07-21
      • 2021-08-01
      • 1970-01-01
      相关资源
      最近更新 更多