Удаление неиспользуемых организаций из крупной информационной базы 1С:ERP — сложнейшая задача. Ситуация усугубляется, если база работает в режиме 24/7, объем данных исчисляется сотнями гигабайт, а штатные механизмы удаления помеченных объектов вызывают критические блокировки СУБД и зависание системы. В этой статье мы подробно разберем, почему возникает эта проблема, какие опасные методы использовать категорически нельзя, и как по шагам реализовать безопасное и быстрое удаление лишних организаций.
Конфигурация 1С:ERP имеет сложную архитектуру связей, из-за чего простое удаление документов одной организации "в лоб" практически невозможно. Проанализируем ключевые преграды:
РеестрДокументов и справочник КлючиРеестраДокументов. Записи в этом регистре могут содержать ключ с удаляемой организацией, даже если сам связанный документ относится к остающейся организации.Иногда разработчики пытаются ускорить процесс с помощью непосредственного удаления объектов в коде. Рассмотрим популярный, но крайне опасный пример:
ОбъектБД = СсылкаБД.ПолучитьОбъект();
ОбъектБД.ОбменДанными.Загрузка = Истина;
ОбъектБД.Удалить();
Почему так делать нельзя на рабочей базе: Свойство ОбменДанными.Загрузка = Истина действительно отключает платформенные проверки и подписки на события при записи/удалении. Однако при физическом вызове метода Удалить() база данных не очистит движения удаляемого документа в многочисленных регистрах. В результате вы получите тысячи "битых" записей в регистрах накопления и сведений, где в качестве регистратора будет стоять битая ссылка <Объект не найден...>. База станет неконсистентной, а последующее тестирование и исправление (ТиИ) с опцией очистки битых ссылок на крупной базе займет несколько суток и полностью парализует работу предприятия.
Аналогично не рекомендуется выполнять прямое удаление через SQL-запросы по GUID организации. База 1С:ERP слишком сложна, и ручное вычищение всех связанных таблиц на уровне СУБД гарантированно приведет к непредсказуемому поведению системы.
Самый безопасный программный способ удаления заключается в строго структурированном, поэтапном (каскадном) удалении данных с проверкой ссылочной целостности и небольшими порциями (транзакциями), чтобы не вызывать блокировок у активных пользователей.
Разберем алгоритм по шагам:
Шаг 1. Перенос файлов во внешние тома. Если присоединенные файлы хранятся в СУБД, перед началом удаления обязательно настройте их хранение на диске (внешние тома) и запустите регламентное задание по их переносу. Это значительно уменьшит размер таблиц и ускорит транзакции удаления.
Шаг 2. Временное снятие дат запрета редактирования. Убедитесь, что для пользователя, под которым запускается обработка очистки, временно отключены даты запрета изменения данных прошлых периодов. Иначе платформа заблокирует любые изменения исторических документов.
Шаг 3. Каскадное удаление данных. Напишите обработку, которая будет последовательно очищать данные в следующем порядке:
ОбменДанными.Загрузка = Истина, так как оно безопасно при установке пометки (но не при физическом удалении!).НайтиПоСсылкам().Организации.Пример кода для безопасной порционной пометки документов на удаление с задержкой (чтобы СУБД "успевала дышать" в режиме 24/7):
Выборка = Документы.РеализацияТоваровУслуг.Выбрать(); // Или запрос по конкретной организации
Пока Выборка.Следующий() Цикл
Если Выборка.Организация = УдаляемаяОрганизация И Не Выборка.ПометкаУдаления Тогда
ДокОбъект = Выборка.ПолучитьОбъект();
ДокОбъект.ОбменДанными.Загрузка = Истина;
ДокОбъект.УстановитьПометкуУдаления(Истина);
// Делаем микропаузу каждые N документов для исключения блокировок
Если КонтрольныйСчетчик % 100 = 0 Тогда
Приостановить(1); // Приостанавливает выполнение на 1 секунду
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если процесс удаления затягивается на недели из-за высокой нагрузки на базу, а пользователи продолжают работать, примените механизм разграничения доступа на уровне записей (RLS). Запретите доступ к удаляемым организациям для всех пользователей, кроме технической учетной записи, которая выполняет удаление. Это позволит "скрыть" ненужные данные из интерфейсов и отчетов мгновенно, а физическую очистку выполнять в фоновом режиме, медленно и без спешки.
Для очень крупных баз (сотни гигабайт и терабайты) процесс удаления исторических данных может оказаться экономически нецелесообразным из-за затрат времени и рисков получить "битую" базу. В таких случаях гораздо эффективнее использовать обратный подход:
В результате вы за минимальное время получите чистую, быструю, оптимизированную базу без исторического мусора и скрытых ошибок ссылочной целостности, а старую базу оставите в режиме "только для чтения" в качестве архива.