10.03.2021, 15:11 | #1 |
Участник
|
Denis Trunin's Blogs: Implementing Dynamics AX 2009/2012 database cleanup
Источник: https://denistrunin.com/ax2012-sqldelete/
============== Describes a custom framework for performing a periodic database cleanup Источник: https://denistrunin.com/ax2012-sqldelete/
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору. |
|
10.03.2021, 21:37 | #2 |
Боец
|
Я бы не стал такой способ применять. Ну во-первых где наши DeleteActions и где фильтрация по компаниям? Во вторых, код на голом SQL всегда сулит проблемы, если что-то сделать неаккуратно. Далее - где обработка эксепшенов и повторов, если что-то залочилось чем-то и нужно повторить? Если проблема блокировок есть, то уровень SQL может усугубить.
Что мешает сделать то же самое на X++? Если правильно приготовить код, то из AX он удаляется ничуть не хуже (отключить логи, отключить DeleteActions и обработать их отдельным шагом?). А ведь DeleteActions как раз таки одна из главных проблем при удалении parent tebles. А где выполняется логика из метода Delete()? В общем случае задача быстрого удаления голым SQL не решается. Каждую удаляемую сущность нужно анализировать индивидуально, разбивать на последовательные логические шаги. В этом основная сложность и только такой подход применим. В конечном итоге, если вы удаляете исторические записи с критерием по дате, то проблемы перформанса могут наблюдаться при первом запуске. Далее, если систематично удалять на ежедневной основе, то не вижу особых проблем с производительностью. Как-то так. |
|
|
За это сообщение автора поблагодарили: mazzy (2), skuull (2). |
10.03.2021, 21:49 | #3 |
Боец
|
Как-то встретил код, простой как грабли. Стояла задача удалить исторические записи, их там было под десяток миллионов. Товарищи не заморачивались: обычный WhileSeleсt выбирал и удалял порциями по, условно, 100 записей. Потом пауза пару секунд и новая порция. Удаляло оно несколько недель, круглосуточно. Но никто даже не заметил. На реализацию потратили наверное часа пол. А то, что оно удаляло неделями - не особо кого-то интересовало. Опять же, если это запускать ежедневно батчем, то и хлам копиться не будет.
|
|
|
За это сообщение автора поблагодарили: Vadik (1). |
10.03.2021, 23:56 | #4 |
Участник
|
а вот поддержу своим +1
и тут даже не то, что код простой, а то, что на ПРОДе скорее всего включен RecoveryModel=Full и изменяя много записей быстро есть огромная вероятность переполнить диск на котором лежит TransactionLog и остановить фсё нафик. а потом получить многочасовой rollback. или подобраться к самой границе ресурсов и получить бэкап из которого невозможно восстановить. полностью согласен, что удалять надо порциями, сообразуясь с размерами дисков, политикой бэкапов и резервов под transaction log |
|
11.03.2021, 00:19 | #5 |
Участник
|
Цитата:
но есть случай, когда процедуру действительно приходится писать на T-SQL. это ВНЕЗАПНЫЙ cleanup. это когда "не было никогда и вот опять" база выросла и ВНЕЗАПНО заполнила ВСЁ. в этом случае, нужно сохранить 1-5% от всех записей в логах, а остальное грохнуть как можно скорее. в этом случае стоит попросить технологическое окно в несколько часов, сделать stop world, перевести базу в монопольный режим и (возможно) в Simple model. Далее SQL-скриптами: * перенести нужный 1-5% записей в stage таблицы, * сделать truncate table (не задействует transaction log) * перенести нужные записи из stage обратно в рабочие. затем вернуть базу из монополного режима в нормальный. |
|
11.03.2021, 04:04 | #6 |
Участник
|
Ну идея была как раз в том, чтобы не удалять неделями и выполнять удаление без остановки. А так да, если это устраивает(плюс десятки разных джобов в разных компаниях), то это и не надо.
Какой-то обработки исключений осознано нет, если они случились, пакет должен падать, т.е. исключение при удалении данных показывает что что-то явно пошло не так. По "DeleteActions" - предполагается что должен быть анализ который выявит таблицы и связи между ними. Я об этом написал. Да и в принципе даже если что-то останется, это можно доудалить К тому же если посмотрите примеры, там миксуются подходы, т.е. для таблиц со сложной структурой используется стандартный while select delete, т.е. опять же надо смотреть что лучше подходит Т.е. данный framework позволит вам решать разные задачи, если взять ваш пример когда оно работало неделю, вы также можете написать класс в данном стиле, при этом получите базовый интерфейся для запуска и возможность отобразить прогресс, чтобы понять работает ваш джоб или нет, объем кода по сути вырастет незначительно. Но если таблица простая, то зачем нагружать сервер выполняя часами этот while select? Цитата:
Далее SQL-скриптами:
* перенести нужный 1-5% записей в stage таблицы, * сделать truncate table (не задействует transaction log) * перенести нужные записи из stage обратно в рабочие. Цитата:
есть огромная вероятность переполнить диск на котором лежит TransactionLog
Последний раз редактировалось trud; 11.03.2021 в 04:40. |
|
11.03.2021, 09:43 | #7 |
Участник
|
Я хотел тоже про delete actions, но успели до меня. Хочется ещё добавить про код который могут дописать в делиты и прочий код который вы радостно игнорируете потенциально разваливая данные и ваш анализ не особо поможет если код допишут после анализа или его допишет вендор, который ваш код анализировать не будет
|
|
11.03.2021, 09:56 | #8 |
Участник
|
Процесс построен немного по другому - т.е. вы когда анализуете что удалять, вы обычно не хотите никаких delete action и тем более выполнения кода на delete методах. Иначе это как бы станно получается, а если эти данные которые допишет вендор не надо удалять? Т.е. мы же говорим о чистке базы, а не о какой-то пользовательской операции.
Т.е. представьте что кто-то добавит метод интеграции на очищаемую таблицу (к примеру в delete), и вы получите много интерестных сообщений Большинство стандартных методов сделано с игнорированием delete action(и это как бы правильно на мой взгляд), т.е. тут ничего не развалится Последний раз редактировалось trud; 11.03.2021 в 10:08. |
|
|
За это сообщение автора поблагодарили: EVGL (2). |
11.03.2021, 12:04 | #9 |
Moderator
|
Удаление напрямую через SQL имеет одно большое преимущество: Можно просто использовать оператор типа
X++: DELETE TOP(10000) FROM [dbo].[batchjobhistory] WHERE enddatetime < Dateadd(day, -30, Getdate()) |
|
11.03.2021, 13:53 | #10 |
Участник
|
Так тоже можно, но без индекса по enddatetime будет блокировка всей таблицы. Можно конечно сделать индексов, но можно и без этого, только выбирать по enddatetime, а удаление делать по кластерным ключам
Последний раз редактировалось trud; 11.03.2021 в 13:56. |
|
11.03.2021, 13:58 | #11 |
Moderator
|
Цитата:
Хотя да - в общем случае ты прав, если объем большой - то стоит подумать над индексами. У меня у одного клиента так чистятся история батчей, AIFMessageLog, EventCUD и inventLogSumTTS (там не мной была сделана доработка, которая записи не удаляет, а помечает к удалению, а ночной батч их потом чистит). Последний раз редактировалось fed; 11.03.2021 в 15:51. |
|
11.03.2021, 14:21 | #12 |
Участник
|
Ну batchjobhistory это не особо нагруженная табличка. Из последних примеров - это проект аудита производительности и InventSum на 70млн записей большинство из которых закрыто и работающая 24*7 система.
Ну т.е. альтернатива это то что написал mazzy, останавливать систему, переливать данные. Но на практике такое довольно сложно сделать. С описанным подходом удаляло где-то полдня, нагрузку особо не давало и ничего не блокировало. Ну и получилось продолжить проект, решая уже другие проблемы |
|
11.03.2021, 15:53 | #13 |
Участник
|
Цитата:
Цитата:
Либо таки "periodic database cleanup", либо внезапно "70млн записей большинство из которых закрыто" |
|
11.03.2021, 15:54 | #14 |
Модератор
|
Цитата:
__________________
-ТСЯ или -ТЬСЯ ? Последний раз редактировалось Vadik; 11.03.2021 в 15:57. |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
11.03.2021, 16:50 | #15 |
Участник
|
Цитата:
Ну т.е. что удобнее - 20 джобов(которые бы нежелательно запускать вместе) или один? По факту люди кучу времени тратят на эту настройку если число компаний велико.или вообще забивают на это По поводу смотреть на лог - он позволит быстро диагностировать проблемы. Из недавнего - клиент пожаловался что очистка InventSum(стандартная) не работает плюс стопит всю систему. Лог выявил что кол-во удаленных записей было больше 2 миллионов(что явно ненормально, это был не первый запуск). Стандартная процедура на таких объемах довольно сильно притормаживает систему, до состояния пользователи звонят и жалуются(это по поводу вашего коментария что неплохо работает) Оказалось что кто-то запустил проверку целостности системы, которая как оказалось пересоздает все удаленные InventSum. Была дана рекомендация этого не делать Ну т.е. без лога это было бы сложно понять, логи наше все |
|
11.03.2021, 17:13 | #16 |
Участник
|
Цитата:
почти на всех проектах, где используют компании, подобное видел. кроме очистки бывают и другие задания, которые надо запускать подобным образом. на мой взгляд, нет никаких причин, чтобы очистка сама занималась компаниями в обход стандартных механизмов. |
|
11.03.2021, 17:45 | #17 |
Участник
|
Идея состояла в том, чтобы сделать что-то универальное. т.е. класс очистки состоит из пустого метода execute, переданной таблицы с параметрами и режима запуска.
что туда писать это дело разработчика. Ну т.е. хочешь удаление со всеми методами и delete actions, которое работает неделю - пишешь так, плюс в базом классе есть некоторые вспомогательные методы для логирования промежуточного прогресса. Согласись что смотреть на джоб который работает неделю не понимая что он делает и сполько осталось довольно сложно? Хочешь быстрый SQL - пишешь быстрый SQL, опять же некоторые хелперы есть Знаешь что уже есть стандартный класс, который "работает неплохо" и хочешь использовать его, используешь его. Требования раздельного удаления по компаниям я не видел, но даже если и будет - никто не мешает реализовать, структура очень базовая, поэтому и гибкая |
|
|
За это сообщение автора поблагодарили: mazzy (2), sukhanchik (6). |
12.03.2021, 12:39 | #18 |
Модератор
|
Странно, мне казалось весь блог был про то насколько T-SQL быстрее архаичного X++, ну да ладно. Чем фреймворк отличается от batch job с множественными batch tasks - тоже решительно непонятно.
P.S. Заставить onhand cleanup / aggregation бодаться с параллельно работающим consistency check, это конечно мощный аргумент в пользу кастомного фреймворка - один сворачивает, другой разворачивает, работа кипит - красота. А склад там параллельно не закрывался и реиндексация не шла? Ну, чтобы уж наверняка Цитата:
Требования раздельного удаления по компаниям я не видел, но даже если и будет - никто не мешает реализовать, структура очень базовая, поэтому и гибкая
__________________
-ТСЯ или -ТЬСЯ ? Последний раз редактировалось Vadik; 12.03.2021 в 12:41. |
|
12.03.2021, 13:40 | #19 |
Участник
|
Цитата:
Как делаете очистку SalesParm..? Она точно блокирует текущие обработки, т.е. кто-то должен озадачится запуском когда не обрабатываются заказы Я не работал с разными регионами в одной системе, у них что разные параметры для заданий очистки в зав-ти от компании? Т.е. вот так это выглядит в предложенном решении, одна форма настройки на все, один batch job на все, статистика в разрезе по задаче Т.е. основная задача которая решается - реализовать периодическую очистку и убедиться что она работает как ожидается, не входит в конфликт с существующими процессами в системе Последний раз редактировалось trud; 12.03.2021 в 13:53. |
|
|
За это сообщение автора поблагодарили: gl00mie (5). |
13.03.2021, 16:15 | #20 |
Модератор
|
Цитата:
Цитата:
А как вы делаете очистку InventSum. Там 3 джоба(агрегирование, wms, on-hadn), которые нужно запускать в каждой компании. Ну т.е. если много компаний запускаете много джобов? в одно и тоже время или разбиваете?
Цитата:
Как делаете очистку SalesParm..? Она точно блокирует текущие обработки, т.е. кто-то должен озадачится запуском когда не обрабатываются заказы
__________________
-ТСЯ или -ТЬСЯ ? |
|
|
|