Как очистить огромный регистр сведений в файловой базе 1С и избежать переполнения памяти

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

При работе с крупными массивами данных в 1С:Предприятие, особенно в файловом варианте базы данных (формат .1CD), разработчики часто сталкиваются с неожиданным поведением системы. Одной из таких проблем является попытка очистки независимого регистра сведений, содержащего десятки миллионов записей. Казалось бы, простая операция записи пустого набора должна выполняться мгновенно, но на практике она может привести к поглощению всего объема оперативной памяти (20 Гб и более) и последующему аварийному завершению работы программы. В этой статье мы подробно разберем, почему это происходит, как устроены механизмы платформы и какими способами можно эффективно решить данную задачу.

Почему 1С потребляет много памяти при записи пустого набора

Рассмотрим внутренние механизмы работы платформы. Когда мы вызываем метод Записать(Истина) для пустого набора записей без установленного отбора, система интерпретирует это как команду на полное замещение всех существующих данных в таблице регистра. В серверном варианте (SQL) эта задача ложится на плечи СУБД, которая оптимизирует транзакцию. Однако в файловом варианте за все отвечает движок 1С.

Проанализируем основные причины «прожорливости» системы:

  1. Журналирование транзакции: Платформа 1С обязана гарантировать целостность данных. Чтобы иметь возможность откатить операцию в случае сбоя, система должна зафиксировать состояние удаляемых данных. При удалении 28 миллионов записей одним махом создается колоссальный объем метаданных в оперативной памяти, описывающих состояние объектов до начала операции.
  2. Индексные страницы: Регистры сведений практически всегда имеют индексы. Удаление записи влечет за собой необходимость обновления индексного дерева. Платформа загружает индексные страницы в кэш для их модификации. На больших объемах данных индексы начинают фрагментироваться и разрастаться в памяти быстрее, чем система успевает их освобождать.
  3. Объектный кэш: Несмотря на то что мы записываем «пустоту», менеджер памяти 1С вынужден идентифицировать все существующие записи, подлежащие удалению, чтобы корректно обновить внутренние таблицы. Это приводит к созданию огромного количества временных объектов в памяти процесса.

Мифы об ограничениях файловой базы

Существует распространенное мнение, что файловая база ограничена 4 Гб на одну таблицу. Давайте проясним ситуацию. В современных версиях платформы (начиная с 8.3.8) это ограничение можно обойти. Размер таблицы зависит от размера страницы данных (4, 8, 16, 32 или 64 Кб). При использовании страницы 64 Кб размер одной таблицы может достигать нескольких терабайт. Однако использование 64-разрядного клиента позволяет процессу 1cv8.exe адресовать более 4 Гб оперативной памяти, что мы и видим в ситуации автора, когда система «съедает» 20 Гб.

Способ 1. Удаление записей порциями (Batching)

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

Рассмотрим пример кода для порционного удаления:


// Определим количество записей, удаляемых за один раз
РазмерПорции = 50000;
ЗаписейОсталось = Истина;

Пока ЗаписейОсталось Цикл
    
    // Создаем набор записей
    Набор = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
    
    // ВАЖНО: Для независимого регистра без отбора 
    // нам нужно выбрать первые N записей.
    // Если есть ключевые поля (например, Период или Измерения), 
    // лучше использовать их для выборки.
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ " + Строка(РазмерПорции) + "
        |   *
        |ИЗ
        |   РегистрСведений.ИмяВашегоРегистра КАК Рег";
    
    Результат = Запрос.Выполнить();
    
    Если Результат.Пустой() Тогда
        ЗаписейОсталось = Ложь;
    Иначе
        // Используем МенеджерЗаписи для удаления каждой записи из выборки 
        // или формируем наборы с отбором по ключевым полям.
        // Для простоты рассмотрим удаление через МенеджерЗаписи в цикле:
        Выборка = Результат.Выбрать();
        Пока Выборка.Следующий() Цикл
            Менеджер = РегистрыСведений.ИмяВашегоРегистра.СоздатьМенеджерЗаписи();
            ЗаполнитьЗначенияСвойств(Менеджер, Выборка);
            Менеджер.Удалить();
        КонецЦикла;
    КонецЕсли;
    
    // Принудительно вызываем сборку мусора (необязательно, но полезно)
    // или просто даем системе передышку между транзакциями
КонецЦикла;

Обратите внимание: Метод с МенеджерЗаписи.Удалить() работает медленнее, но он наиболее безопасен с точки зрения потребления RAM в файловом режиме, так как каждая операция удаления является отдельной маленькой транзакцией.

Способ 2. Очистка через Конфигуратор (кардинальный метод)

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

Выполним следующие шаги:

  1. Откройте Конфигуратор и найдите нужный регистр сведений.
  2. Если конфигурация находится на поддержке, необходимо разрешить изменения (Конфигурация -> Поддержка -> Настройка поддержки).
  3. Удалите регистр сведений из дерева метаданных.
  4. Выполните Обновление конфигурации базы данных (F7). На этом этапе физическая таблица в файле .1CD будет уничтожена.
  5. Сделайте Загрузку конфигурации из файла (или из поставки), чтобы вернуть структуру регистра обратно, но уже без данных.
  6. Снова обновите конфигурацию базы данных.

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

Способ 3. Использование внешних утилит

В обсуждении упоминалась утилита Tool_1CD. Проанализируем её применимость. Старые версии утилиты действительно не поддерживают новые форматы страниц файловых баз. Однако существуют обновленные версии и скрипты на Python, которые позволяют работать с форматом .1CD напрямую.

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

Завершение операции: Сжатие базы данных

После того как вы успешно удалили миллионы записей любым из вышеперечисленных способов, вы заметите, что файл .1CD не уменьшился в размере. Это особенность файлового движка 1С: он помечает место как свободное, но не отдает его операционной системе автоматически.

Чтобы физически уменьшить размер файла, выполните:

  1. Зайдите в Конфигуратор.
  2. Меню Администрирование -> Тестирование и исправление.
  3. Выберите пункт «Сжатие таблиц информационной базы».
  4. Нажмите «Выполнить».

Только после этой процедуры индексы будут перестроены, а неиспользуемое пространство будет возвращено файловой системе. Это критически важно для производительности базы в будущем.

Выводы

Мы выяснили, что основной проблемой при работе с большими объемами данных в файловой 1С является попытка выполнения массовых операций в рамках одной транзакции. Главное правило: всегда разделяйте обработку больших массивов на порции. Это касается не только удаления, но и записи или изменения данных. Использование 64-битной платформы дает больше ресурсов, но не отменяет необходимости грамотного проектирования алгоритмов очистки.

← На главную