Невозможно удалить самый старый раздел таблицы

Я использую функцию интервального разделения 11g в одной из своих таблиц. Я настроил его для создания однодневных разделов в поле временной метки и создал задание для удаления данных трехмесячной давности. Когда я пытаюсь удалить самый старый раздел, я получаю следующую ошибку:

ORA-14758: Последний раздел в разделе диапазона не может быть удален

Я бы подумал, что «Последний» относится к самому новому разделу, а не к самому старому. Как мне интерпретировать эту ошибку? Что-то не так с моими разделами, или я должен всегда хранить самый старый раздел там?


person Community    schedule 08.09.2009    source источник


Ответы (2)


Да, сообщение об ошибке несколько вводит в заблуждение, но оно относится к последнему СТАТИЧЕСКИ созданному разделу (в DDL исходной таблицы до того, как Oracle начал автоматически создавать разделы. Я думаю, что единственный способ избежать этого - создать искусственный раздел «MINVAL», который вы уверены, что никогда не будут использоваться, а затем сбросьте настоящие разделы выше этого.

[Редактировать после обмена комментариями]

Я предполагаю, что этот тестовый пример воспроизводит вашу проблему:

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'));
person dpbradley    schedule 08.09.2009
comment
По названию раздела я могу сказать, что он был создан автоматически, и что самое странное, я смог удалить статически созданные разделы до этого. Как бы то ни было, я хотел попробовать ваше предложение и получил эту ошибку: изменить таблицу TABLE1 добавить тест раздела ЗНАЧЕНИЯ МЕНЬШЕ ЧЕМ ('07 -JUL-09 11.59.00.000000000 PM '); ОШИБКА в строке 1: ORA-14760: ДОБАВЛЕНИЕ РАЗДЕЛА не разрешено для объектов, разделенных по интервалам. Есть идеи? Спасибо, Пи Джей - person ; 08.09.2009
comment
Хммм ... Я столкнулся с вашей проблемой, и в моем случае это была проблема СТАТИЧЕСКОГО или ДИНАМИЧЕСКОГО позиционирования. Когда я упомянул раздел MINVAL, я думал о воссоздании таблицы с этим единственным разделом (и определенным интервальным разделением), а затем повторной вставкой данных - возможно ли это в вашей ситуации? - person dpbradley; 09.09.2009
comment
Мне не хватает места на диске, таблица огромная. Фактически это может быть первый автоматически созданный раздел. Я могу удалить новые разделы, но ... можете ли вы придумать другой способ решения этой проблемы? - person ; 09.09.2009
comment
Я не пробовал это способом, который пересекал бы типы разделов, но могли бы вы выполнить операции разделов SPLIT или MERGE для перемещения границ? - person dpbradley; 09.09.2009
comment
Отвечая на мой собственный комментарий - SPLIT / MERGE не помогает - я отредактировал свой ответ единственным решением, которое я могу придумать. - person dpbradley; 09.09.2009

Все правильно в ответе dpbradley. Но это можно было бы сделать более безопасным способом, если вы удаляете самые старые разделы:

На самом деле достаточно просто сбросить интервал следующим образом:

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

А затем удалите самый старый раздел.

В противном случае существует риск, что при сбое отбрасываемого раздела у таблицы не будет интервала. Поэтому нужно перехватить все исключения и справиться с этим.

person Rusty    schedule 11.12.2013