Почему 1С зависает после массовой загрузки или удаления объектов, и что в это время делает платформа?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием
← На главную

Многие администраторы и разработчики 1С сталкиваются с пугающей ситуацией: после запуска масштабного удаления помеченных объектов или загрузки через Конвертацию данных 2.0 (КД 2.0), процесс «зависает» на несколько суток. Самое странное происходит в конце: судя по Журналу регистрации, данные уже не пишутся, объекты не меняются, но сеанс остается неактивным, а монитор ресурсов показывает странную активность чтения мелкими порциями. Проанализируем ситуацию, разберем внутренние механизмы платформы и выясним, почему так происходит.

Разберем сценарии возникновения проблемы

Рассмотрим две типичные ситуации, описанные пользователями:

  1. Загрузка данных через КД 2.0: Загрузка идет 8 суток. После этого записи в журнале регистрации прекращаются, но сеанс «висит» еще 3 дня, что-то считывая с диска.
  2. Удаление в ERP (файловая база): К удалению помечено 260 000 объектов. Поиск ссылок длится 15 суток, само удаление — 3 суток. После этого сеанс блокируется еще на 4 дня с надписью «Идет удаление», хотя фактической записи в базу уже нет.

В обоих случаях кнопка «Остановить» в отладчике не помогает. Это означает, что выполнение кода на встроенном языке завершено, и управление перешло к ядру платформы (на уровень C++). Выясним причину такого поведения.

Анализ механизма контроля ссылочной целостности

Когда мы запускаем штатное удаление объектов, платформа выполняет колоссальный объем работы, который не ограничивается простым Object.Delete(). Рассмотрим подробнее, что происходит за кулисами:

Платформа должна гарантировать, что после удаления не останется «битых» ссылок. Для этого строится дерево связей. Если объектов 260 000, то количество проверяемых таблиц и записей может исчисляться сотнями миллионов. Все эти данные платформа сохраняет во временных файлах (папка %TEMP% или каталог в папке сервера 1С).

Проанализируем ситуацию в конце процесса: когда последний объект физически удален, платформе нужно сформировать отчет для пользователя — список тех объектов, которые не удалось удалить из-за наличия ссылок на них. Именно здесь начинаются проблемы:

Особенности работы файлового режима (.1CD)

В файловом режиме (как в примере с ERP) ситуация усугубляется особенностями движка базы данных. Посмотрим на пример: при массовых операциях база работает с временными таблицами внутри файла базы данных или в системных временных файлах.

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

Влияние Конвертации данных 2.0

При загрузке через КД 2.0 используется последовательный разбор XML-файла. Рассмотрим подробнее, почему сеанс висит после загрузки:

  1. Очистка кэша объектов: КД 2.0 хранит в памяти таблицу соответствия загруженных объектов для предотвращения дублей. После завершения загрузки платформа должна корректно освободить эту память. Если файл обмена весил гигабайты, деструкторы объектов могут работать крайне долго.
  2. Фиксация транзакции: Если загрузка шла в одной большой транзакции (что часто бывает при неправильной настройке правил), то ЗафиксироватьТранзакцию() может выполняться несколько часов, пока СУБД сбрасывает логи на диск.

Как избежать подобных «зависаний»?

Чтобы не ждать 18 дней, разберем по шагам правильную стратегию работы с большими объемами данных:

1. Используйте порционную обработку

Никогда не удаляйте и не грузите сотни тысяч объектов одним махом. Посмотрим на пример концептуального кода для удаления порциями:


Выборка = ПомеченныеНаУдаление.Выбрать();
Счетчик = 0;
Пока Выборка.Следующий() Цикл
    НачатьТранзакцию();
    Попытка
        Объект = Выборка.Ссылка.ПолучитьОбъект();
        Объект.Удалить();
        Счетчик = Счетчик + 1;
        ЗафиксироватьТранзакцию();
    Исключение
        ОтменитьТранзакцию();
    КонецПопытки;
    
    Если Счетчик % 1000 = 0 Тогда
        // Освобождаем память и даем платформе "вдохнуть"
        ОбработкаПрерыванияПользователя();
    КонецЕсли;
КонецЦикла;

Важный момент: штатная обработка удаления в 1С 8.3 имеет режим «Удалять порциями», который значительно снижает нагрузку на память и временные файлы.

2. Отключайте лишние механизмы

Перед массовой загрузкой в ERP или Комплексную автоматизацию стоит временно отключить:

3. Инструменты разработчика (ИР)

Для удаления огромного количества объектов профессионалы рекомендуют использовать «Инструменты разработчика». Они позволяют обходить штатный механизм поиска ссылок платформой и выполнять его более оптимальными SQL-запросами, что сокращает время поиска с недель до часов.

Выясним итог: что же происходило у автора темы?

Платформа 1С после завершения записи данных занималась десериализацией и подготовкой отчета о результатах операции. Огромный объем временных данных, накопленный за дни работы, требовал длительного времени на обработку внутренними алгоритмами ядра (C++), которые не транслируются в журнал регистрации и не прерываются отладчиком. Чтение малыми порциями — это признак того, что платформа «переваривала» гигантский временный файл со ссылками, пытаясь построить финальное дерево результатов для отображения пользователю.

← На главную