При длительной эксплуатации информационных баз 1С в них неизбежно накапливается огромное количество объектов, помеченных на удаление. Попытка очистить базу стандартной обработкой «Удаление помеченных объектов» на больших объемах данных часто приводит к аварийному завершению работы платформы с ошибкой «Недостаточно памяти». Разберем причинно-следственные связи этой проблемы и проанализируем проверенные способы ее решения.
Выясним, почему стандартный механизм удаления перегружает оперативную память сервера или клиентского компьютера:
НайтиПоСсылкам. Платформа сканирует все таблицы метаданных и пытается построить единый граф зависимостей в оперативной памяти. Если объектов десятки тысяч, объём этих связей быстро переполняет доступный лимит RAM.Самым быстрым первичным решением является запуск операции удаления в 64-битной версии клиента 1С. 64-разрядный процесс снят с жесткого лимита в 2–4 ГБ RAM и способен использовать всю имеющуюся оперативную память сервера или компьютера. Это позволяет платформе построить крупный граф ссылок без падения по нехватке памяти.
Если запустить 64-битный клиент невозможно или объема памяти все равно не хватает, разберем подход с частичной очисткой по типам метаданных:
Организации, БанковскиеСчетаОрганизаций, основные справочники номенклатуры или контрагентов.Для работы с большими объемами удаляемых данных стандартная обработка может оказаться неэффективной. Проанализируем альтернативные инструменты:
Для гарантированной очистки крупных баз проанализируем программный алгоритм порционной обработки. Мы будем обрабатывать ссылки небольшими пакетами (например, по 100–500 штук) и фиксировать транзакцию на каждом шаге. Рассмотрим пример кода:
МассивПомеченных = НайтиПомеченныеНаУдаление();
РазмерПорции = 200;
ТекущаяПорция = Новый Массив;
Для Каждого СсылкаИзСписка Из МассивПомеченных Цикл
ТекущаяПорция.Добавить(СсылкаИзСписка);
Если ТекущаяПорция.Количество() >= РазмерПорции Тогда
УдалитьПорциюОбъектов(ТекущаяПорция);
ТекущаяПорция.Очистить();
КонецЕсли;
КонецЦикла;
Если ТекущаяПорция.Количество() > 0 Тогда
УдалитьПорциюОбъектов(ТекущаяПорция);
КонецЕсли;
Внутри процедуры УдалитьПорциюОбъектов можно применить прямой метод платформы УдалитьОбъекты с отключенной проверкой ссылочной целостности для мгновенной очистки таблиц:
Процедура УдалитьПорциюОбъектов(МассивУдаляемых)
// Удаляем объекты без построения тяжелого графа ссылок
УдалитьОбъекты(МассивУдаляемых, Ложь);
КонецПроцедуры
Важное примечание: Использование метода УдалитьОбъекты с параметром ПроверятьСсылки = Ложь требует предварительной очистки связанной информации (записей в РегистрыСведений, реквизитов других документов), иначе в базе останутся «битые» ссылки вида «Объект не найден».
После физического удаления объектов из базы рекомендуется выполнить сжатие и обслуживание таблиц СУБД, чтобы вернуть освобожденное дисковое пространство.