При работе с крупными массивами данных в 1С:Предприятие, особенно в файловом варианте базы данных (формат .1CD), разработчики часто сталкиваются с неожиданным поведением системы. Одной из таких проблем является попытка очистки независимого регистра сведений, содержащего десятки миллионов записей. Казалось бы, простая операция записи пустого набора должна выполняться мгновенно, но на практике она может привести к поглощению всего объема оперативной памяти (20 Гб и более) и последующему аварийному завершению работы программы. В этой статье мы подробно разберем, почему это происходит, как устроены механизмы платформы и какими способами можно эффективно решить данную задачу.
Рассмотрим внутренние механизмы работы платформы. Когда мы вызываем метод Записать(Истина) для пустого набора записей без установленного отбора, система интерпретирует это как команду на полное замещение всех существующих данных в таблице регистра. В серверном варианте (SQL) эта задача ложится на плечи СУБД, которая оптимизирует транзакцию. Однако в файловом варианте за все отвечает движок 1С.
Проанализируем основные причины «прожорливости» системы:
Существует распространенное мнение, что файловая база ограничена 4 Гб на одну таблицу. Давайте проясним ситуацию. В современных версиях платформы (начиная с 8.3.8) это ограничение можно обойти. Размер таблицы зависит от размера страницы данных (4, 8, 16, 32 или 64 Кб). При использовании страницы 64 Кб размер одной таблицы может достигать нескольких терабайт. Однако использование 64-разрядного клиента позволяет процессу 1cv8.exe адресовать более 4 Гб оперативной памяти, что мы и видим в ситуации автора, когда система «съедает» 20 Гб.
Это самый надежный программный метод, который позволяет обойти ограничения оперативной памяти. Вместо того чтобы пытаться очистить весь регистр одной транзакцией, мы разделим процесс на множество мелких итераций. Это позволит системе своевременно освобождать память и фиксировать изменения в файле базы данных.
Рассмотрим пример кода для порционного удаления:
// Определим количество записей, удаляемых за один раз
РазмерПорции = 50000;
ЗаписейОсталось = Истина;
Пока ЗаписейОсталось Цикл
// Создаем набор записей
Набор = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
// ВАЖНО: Для независимого регистра без отбора
// нам нужно выбрать первые N записей.
// Если есть ключевые поля (например, Период или Измерения),
// лучше использовать их для выборки.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ " + Строка(РазмерПорции) + "
| *
|ИЗ
| РегистрСведений.ИмяВашегоРегистра КАК Рег";
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
ЗаписейОсталось = Ложь;
Иначе
// Используем МенеджерЗаписи для удаления каждой записи из выборки
// или формируем наборы с отбором по ключевым полям.
// Для простоты рассмотрим удаление через МенеджерЗаписи в цикле:
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Менеджер = РегистрыСведений.ИмяВашегоРегистра.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(Менеджер, Выборка);
Менеджер.Удалить();
КонецЦикла;
КонецЕсли;
// Принудительно вызываем сборку мусора (необязательно, но полезно)
// или просто даем системе передышку между транзакциями
КонецЦикла;
Обратите внимание: Метод с МенеджерЗаписи.Удалить() работает медленнее, но он наиболее безопасен с точки зрения потребления RAM в файловом режиме, так как каждая операция удаления является отдельной маленькой транзакцией.
Если программные методы не помогают или занимают слишком много времени, можно прибегнуть к «хирургическому» вмешательству. Этот метод быстрее всего удаляет данные, так как платформа просто удаляет саму таблицу из базы данных.
Выполним следующие шаги:
.1CD будет уничтожена.Этот метод эффективен, когда нужно очистить сразу несколько огромных регистров, но он требует монопольного доступа к базе и осторожности при работе с поддержкой поставщика.
В обсуждении упоминалась утилита Tool_1CD. Проанализируем её применимость. Старые версии утилиты действительно не поддерживают новые форматы страниц файловых баз. Однако существуют обновленные версии и скрипты на Python, которые позволяют работать с форматом .1CD напрямую.
Важное предостережение: Использование прямого редактирования файла базы данных крайне рискованно. Если просто «вырезать» таблицу, можно нарушить логическую целостность (например, если на этот регистр завязаны итоги, последовательности или другие механизмы платформы). Мы рекомендуем использовать этот способ только в самых крайних случаях и только на копии базы.
После того как вы успешно удалили миллионы записей любым из вышеперечисленных способов, вы заметите, что файл .1CD не уменьшился в размере. Это особенность файлового движка 1С: он помечает место как свободное, но не отдает его операционной системе автоматически.
Чтобы физически уменьшить размер файла, выполните:
Только после этой процедуры индексы будут перестроены, а неиспользуемое пространство будет возвращено файловой системе. Это критически важно для производительности базы в будущем.
Мы выяснили, что основной проблемой при работе с большими объемами данных в файловой 1С является попытка выполнения массовых операций в рамках одной транзакции. Главное правило: всегда разделяйте обработку больших массивов на порции. Это касается не только удаления, но и записи или изменения данных. Использование 64-битной платформы дает больше ресурсов, но не отменяет необходимости грамотного проектирования алгоритмов очистки.