:: Не фоксом единым
Oracle. "Умное" удаление партиций
Pekpytep
Автор

Сообщений: 727
Откуда: Луганск
Дата регистрации: 19.10.2010
Всем привет.
Есть некий большой лог, партиционированный по дате с интервалом в 1 день. Возник вопрос его периодической чистки, но учитывая что даже пустая партиция резервирует под себя дисковое пространство (насколько я помню), думаю имеет смысл именно дропать ненужные партиции, а не просто удалять данные. Возник вопрос, как определить список партиций подходящих под критерии удаления по значению ключа. Все что пока пришло на ум, это нечто типа

select partition_name from user_tab_partitions
where table_name = ... and to_date(substr(high_value, ...), 'yyyy-mm-dd') < (sysdate - :p_interval));

Есть подозрение, что я изобретаю велосипед с квадратными колесами и у оракла должна быть штатная функция определения имени партиции(й) по значению(диапазону).
Действительно ли такая функция есть?
Ratings: 0 negative/0 positive
Re: Oracle. "Умное" удаление партиций
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Не понятно - секции динамически добавляются? Ты не имеешь контроля над присваиваемым им именам? Или секции статические, скажем по номеру дня (31 штука) и просто периодически удаляются данные за прошлые месяцы?
Просто я не вижу особой нужды в функции "определения имени партиции по значению" Тем более что схем секционирования хватает и помимо Range - где вообще теряет смысл подобная задача...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. "Умное" удаление партиций
Pekpytep
Автор

Сообщений: 727
Откуда: Луганск
Дата регистрации: 19.10.2010
Как добавляются - не уверен, из дому нет доступа к базе. Имена генерятся ораклой автоматически. Секций по количеству дней, похоже что их там чуть менее 2 тыс.(период около 4-5 лет). Ни данные, ни секции до сегодняшнего дня не удалялись.

Igor Korolyov
Просто я не вижу особой нужды в функции "определения имени партиции по значению"
А как тогда сделать чтобы больше туда руками не лезть? Чтобы все чистилось автоматом по джобе в любой момент времени нужно как-то определять список секций-кандидатов на удаление.
Ratings: 0 negative/0 positive
Re: Oracle. "Умное" удаление партиций
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Очевидно что проще всего генерить их имена явно, включая в имя YYYYMMDD (если критерий секционирования это range на 1 день) и соответственно удалять старые будет несложно не залазя в high_value - по тем же самым именам... Равно и создавать новые...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. "Умное" удаление партиций
Pekpytep
Автор

Сообщений: 727
Откуда: Луганск
Дата регистрации: 19.10.2010
Сделать это будет примерно так же легко, как увидеть в полдень 20-летнюю девственницу верхом на единороге.
Мы на аутсорсе, база нам не принадлежит. Нужно убедить заказчика в необходимости этих телодвижений ПМу, согласовать изменения, аналитикам написать ТЗ, создать задачи в джире, мне переделать, нашим тестерам протестировать, их тестерам протестировать, внедрить. Это месяца полтора, в лучшем случае, а дисковое пространство закончилось уже сейчас.
Потом, переименовать будет тоже не так уж просто. Легче всего было бы переименовать старую таблицу, создать новую с таким же именем и перелить данные, но на диске нет свободного места. Переименовывать секции с автоматически сгенерированными именами (имена которых еще и отличаются на дев, тест и прод) вручную - то еще удовольствие, а чтобы написать скрипт автоматически переименовывающий имена по какому-то правилу нужно опять же определить текущее имя секции по значению. В общем, не вариант. В перспективе может кто-нибудь когда-нибудь и переделает, но сейчас придется, видимо, заморачиваться с выковыриванием значения из high_value.
Ratings: 0 negative/0 positive
Re: Oracle. "Умное" удаление партиций
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Сейчас - да. На будущее - как хотите, можно сделать получше, можно оставить как есть. Решение же есть Если владелец базы дурак, то вполне логично что и решения для его базы будут дурацкие


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. "Умное" удаление партиций
Pekpytep
Автор

Сообщений: 727
Откуда: Луганск
Дата регистрации: 19.10.2010
Хм, задача осложнилась тем, что user_tab_partitions.high_value имеет тип LONG, как выяснилось. Пришлось прокачать свой велосипед, добавив к нему еще один велосипед (чтобы я мог крутить педали пока не дали пока кручу педали). В общем, может еще кому пригодится:

with
tmp_xml as
(
select
dbms_xmlgen.getxmltype('select table_name, partition_name, partition_position, high_value from user_tab_partitions where table_name = ''MY_TABLE''') as x
from dual
),
tmp_list as
(
select
extractValue(rws.object_value, '/ROW/PARTITION_NAME') partition_name
, extractValue(rws.object_value, '/ROW/PARTITION_POSITION') partition_position
, extractValue(rws.object_value, '/ROW/HIGH_VALUE') high_value
from tmp_xml x, table(xmlsequence(extract(x.x, '/ROWSET/ROW'))) rws
)
select
partition_name
from tmp_list
where to_date(substr(high_value, 11, 10), 'yyyy-mm-dd') < sysdate - :p_interval;
Ratings: 0 negative/0 positive
Re: Oracle. "Умное" удаление партиций
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Да, я когда-то функцию на pl/sql городил (точнее искал на просторах сети готовое решение ) чтобы с long полем более-менее нормально работать (в clob его загонял, потом можно было в запрос такую функцию вставлять) - через DBMS_SQL. Тоже для метаданных - но мне нужен был доступ к исходникам триггеров и ещё чему-то такого же рода, в long хранящемуся... Наверное тогда ещё с xml не было варианта, или не набрёл просто


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. "Умное" удаление партиций
Pekpytep
Автор

Сообщений: 727
Откуда: Луганск
Дата регистрации: 19.10.2010
Еще один вариант удаления секций для лога на который нет FK:
DECLARE
v_obj_id all_objects.object_id%TYPE;
v_archive_depth NUMBER := 30;
e_partition_not_exists EXCEPTION;
PRAGMA exception_init(e_partition_not_exists, -02149);
BEGIN
SELECT
data_object_id
INTO v_obj_id
FROM all_objects o, all_tab_partitions p
WHERE p.table_owner = 'MY_SCHEMA'
AND p.table_name = 'MY_TABLE'
AND p.partition_position = 1
AND o.owner = p.table_owner
AND o.object_name = p.table_name
AND o.subobject_name = p.partition_name;
FOR cpart IN (
SELECT * FROM(
WITH T AS (SELECT TRUNC(log_date) d
FROM my_table PARTITION (dataobj_to_partition(my_table, v_obj_id))
WHERE ROWNUM = 1)
SELECT D+ROWNUM-1 part_date FROM t
CONNECT BY LEVEL < TRUNC(sysdate) - (SELECT D FROM T)
)
WHERE part_date < TRUNC(sysdate) - v_archive_depth
)
LOOP
BEGIN
EXECUTE IMMEDIATE 'ALTER TABLE my_table DROP PARTITION FOR (TO_DATE('''||to_char(cpart.part_date, 'yyyymmdd') || ''',''YYYYMMDD''))';
EXCEPTION
WHEN e_partition_not_exists THEN NULL;
END;
END LOOP;
EXCEPTION
WHEN no_data_found THEN NULL;
END;
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 11 Касьянов alex;  (Гостей: 9)

© 2000-2024 Fox Club 
Яндекс.Метрика