Методы удаления старых данных в базах данных Oracle - PullRequest
6 голосов
/ 11 июня 2009

У нас есть зрелое приложение базы данных Oracle (в производстве более 10 лет), и в течение этого времени мы использовали собственные сценарии, предназначенные для удаления старых данных, которые больше не нужны. Они работают, выпуская операторы удаления для соответствующих таблиц, в цикле с частыми коммитами, чтобы избежать перегрузки системы при вводе-выводе или использовании слишком большого пространства отмены.

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

В течение многих лет мы рассматривали лучшие методы. В прошлом я слышал, что люди использовали многораздельные таблицы для управления пожатием старых данных - например, один месяц на раздел и ежемесячное удаление самого старого раздела. Основным недостатком этого подхода является то, что наши правила сбора урожая выходят за рамки «удалить месяц X». Пользователи могут указать, как долго данные должны оставаться в системе, основываясь на значениях ключей (например, в таблице счетов-фактур учетная запись foo может быть удалена через 3 месяца, но может потребоваться, чтобы строка учетной записи оставалась в течение 2 лет).

Существует также проблема ссылочной целостности; В документации Oracle говорится об использовании разделов для очистки данных, главным образом в контексте хранилищ данных, где таблицы, как правило, являются гиперкубами. Наш подход ближе к концу OLTP, и данные за месяц X обычно имеют связь с данными за месяц Y. Создание правильных ключей разделения для этих таблиц было бы в лучшем случае щекотливым.

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

Мы застряли с использованием удалений в обозримом будущем, или есть другие, более умные способы борьбы с пожинанием?

Ответы [ 4 ]

4 голосов
/ 11 июня 2009

По большей части я думаю, что вы застряли при удалении.

Ваши комментарии о сложности использования разделов в вашем случае, вероятно, препятствуют их эффективному использованию (используются разные даты удаления в зависимости от типа записи), но возможно, что вы можете создать столбец «удалить дату» на записи, которые вы могли бы разделить на? Недостатком было бы сделать обновление довольно дорогим, так как изменение даты удаления может привести к переносу строки, поэтому ваше обновление действительно будет реализовано как удаление и вставка.

Может даже случиться, что даже тогда вы не сможете использовать операции разбиения DDL для удаления старых данных из-за проблем ссылочной целостности, но разбиение может по-прежнему выполнять физическую кластеризацию удаляемых строк, поэтому требуется меньше блоков изменять порядок их удаления, смягчающий влияние на буферный кеш.

0 голосов
/ 16 июня 2009

У нас та же проблема, используя ту же стратегию. Если ситуация становится действительно плохой (очень фрагментированное распределение индексов, таблиц, ...), мы пытаемся применить действия по восстановлению пространства.

В таблицах должно быть разрешено перемещение строк (например, для воспоминаний): изменить таблицу TTT включить движение строки; изменить таблицу TTT термоусадочную площадь; а затем перестройте все индексы.

Я не знаю, как у вас обстоят дела с окнами обслуживания, если приложение нужно постоянно использовать, то сложнее, если нет, вы можете сделать некоторую «перепаковку», когда она не в сети. «alter table TTT move tablespace SSSS» выполняет большую работу по устранению путаницы при переписывании таблицы. Вы также можете указать новые параметры хранения, такие как управление экстентами, размеры, ... посмотрите в документах.

Я использую такой скрипт, чтобы создать скрипт для всей базы данных:

SET SQLPROMPT "-- "
SET ECHO OFF
SET NEWPAGE 0
SET SPACE 0
SET PAGESIZE 0
SET FEEDBACK OFF
SET HEADING OFF
SET TRIMSPOOL ON
SET TERMOUT OFF
SET VERIFY OFF
SET TAB OFF
spool doit.sql
select 'prompt Enabling row movement in '||table_name||'...'||CHR (10)||'alter table '||table_name||' enable row movement;' from user_tables where table_name not like '%$%' and table_name not like '%QTAB' and table_name not like 'SYS_%';
select 'prompt Setting initial ext for '||table_name||'...'||CHR (10)||'alter table '||table_name||' move storage (initial 1m);' from user_tables where table_name not like '%$%' and table_name not like '%QTAB' and table_name not like 'SYS_%';
select 'prompt Shrinking space for '||table_name||'...'||CHR (10)||'alter table '||table_name||' shrink space;' from user_tables where table_name not like '%$%' and table_name not like '%QTAB' and table_name not like 'SYS_%';
select 'prompt Rebuilding index '||index_name||'...'||CHR (10)||'alter index '||index_name||' rebuild;' from user_indexes where status = 'UNUSABLE';
spool off
prompt now check and then run @doit.sql
exit
0 голосов
/ 12 июня 2009

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

0 голосов
/ 11 июня 2009

Удалить не так уж и плохо, при условии, что вы перестроите свои индексы . Oracle восстановит страницы, которые больше не содержат данных.

Однако, начиная с 8i (и, вероятно, все еще), он не будет должным образом восстанавливать страницы индекса, которые больше не содержат действительных ссылок. Хуже того, поскольку листы индекса были соединены в цепочку, вы можете попасть в ситуацию, когда он начнет ходить по узлам листа, чтобы найти строку. Это может привести к довольно значительному падению производительности: запросы, которые обычно занимают секунды, могут занимать минуты. Падение также было очень внезапным: однажды все будет хорошо, а на следующий день - нет.

Я обнаружил это поведение (в нем была ошибка Oracle, как и у других), с помощью приложения, которое использовало увеличивающиеся ключи и регулярно удаляло данные. Нашим решением было инвертировать части ключа, но это не поможет вам с датами.

...