Как безопасно удалить большой объем данных из регистра сведений 1С средствами SQL и встроенного языка

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

При работе с высоконагруженными системами на базе 1С:Предприятие часто возникает ситуация, когда технические регистры сведений (например, логи, история версий или кэш расчетов) разрастаются до огромных размеров. В рассматриваемом случае объем данных составляет 35 ГБ (оценить распределение места можно через SQL Базомер (8.2, 8.3)). Попытка очистить такой регистр «в лоб» через стандартные инструменты платформы или простую запись пустого набора записей часто приводит к переполнению tempdb, разрастанию лога транзакций (LDF-файла) и последующему переходу базы данных в режим восстановления (Recovery). Разберем по шагам, как решить эту задачу эффективно и безопасно.

Анализ проблемы: почему стандартные методы дают сбой

Когда мы выполняем команду Набор.Записать() для очистки всего регистра, платформа 1С открывает одну гигантскую транзакцию. SQL Server вынужден фиксировать удаление каждой строки в логе транзакций, чтобы иметь возможность откатить изменения в случае сбоя. При объеме в 35 ГБ объем метаданных об удалении может превысить свободное место на диске, что приводит к остановке сервера. Проанализируем ситуацию: для успешной очистки нам нужно либо разбить операцию на мелкие части, либо использовать инструменты SQL, которые минимизируют логирование.

Способ 1. Удаление данных порциями через встроенный язык 1С

Это самый безопасный метод с точки зрения логики платформы, так как он учитывает все механизмы объектной техники 1С. Основная идея — не удалять всё сразу, а фиксировать изменения небольшими порциями. Рассмотрим реализацию для разных типов регистров.

Для независимого регистра сведений, если данных очень много, лучше всего использовать удаление и обработку записей по фильтрам (например, по определенным измерениям, периоду или по конкретным узлам обмена). Однако, если нужно очистить всё, можно воспользоваться следующим алгоритмом:


Набор = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
Набор.ОбменДанными.Загрузка = Истина; // Отключаем лишние подписки и проверки
// Если регистр позволяет, устанавливаем отбор по какому-либо критерию (например, по дате)
// И выполняем запись пустого набора для этой порции
Набор.Записать();

Если регистр подчинен регистратору, удаление происходит через очистку движений документов. Разберем пример кода, который выбирает регистраторы и очищает их движения порциями, чтобы не перегружать tempdb:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |   Т.Регистратор КАК Регистратор
    |ИЗ
    |   РегистрСведений.ИмяВашегоРегистра КАК Т";

Выборка = Запрос.Выполнить().Выбрать();
Набор = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
Набор.ОбменДанными.Загрузка = Истина;

Пока Выборка.Следующий() Цикл
    Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
    Набор.Записать(); // Каждая итерация — отдельная транзакция
КонецЦикла;

Важный момент: использование ОбменДанными.Загрузка = Истина критически важно, так как это предотвращает срабатывание тяжелых обработчиков событий «ПриЗаписи», которые могут замедлить процесс в десятки раз.

Способ 2. Использование прямой SQL-команды TRUNCATE

Если база данных находится на SQL Server и вам нужно очистить регистр полностью, самым быстрым способом будет команда TRUNCATE TABLE. В отличие от DELETE, эта команда не записывает удаление каждой строки в лог транзакций, а просто освобождает страницы памяти, занятые таблицей.

Рассмотрим последовательность действий:

  1. Выясним имя таблицы в SQL. Для этого в 1С используем функцию ПолучитьСтруктуруХраненияБазыДанных() или специализированные обработки для просмотра структуры БД. Таблица будет иметь имя вида _InfoRgXXXX.
  2. Перед выполнением команды убедимся, что на таблицу нет внешних ссылок (Foreign Keys). В типовых конфигурациях 1С для регистров сведений они создаются редко, но проверка необходима.
  3. Выполним скрипт в SQL Management Studio:

-- Будьте крайне осторожны! Данные удаляются мгновенно и безвозвратно.
TRUNCATE TABLE _InfoRg12345; -- Замените на ваше имя таблицы

Преимущества: операция выполняется практически мгновенно, tempdb и лог транзакций не растут. Риски: 1С может «не заметить» удаления данных на уровне кэша сервера приложений. После выполнения операции рекомендуется перезапустить службу кластера 1С.

Способ 3. Оптимизация через режим восстановления базы (Recovery Model)

Если вы все же решили использовать DELETE через SQL или удаление средствами 1С, проанализируем настройки самой базы данных. Если база находится в режиме Full Recovery Model, каждое удаление 35 ГБ данных будет порождать записи в логе аналогичного объема.

Выясним, как ускорить процесс:

  1. Переведем базу данных в режим Simple Recovery Model перед началом удаления.
  2. Выполним удаление данных (через 1С порциями или через SQL).
  3. Вернем режим Full и обязательно сделаем полный бэкап базы.

Это позволит SQL Server не накапливать историю изменений в LDF-файле, а зацикливать его использование, что предотвратит нехватку места на диске.

Способ 4. Манипуляции с метаданными в Конфигураторе

Существует «хитрый» способ очистки данных штатными средствами, который иногда работает быстрее программного удаления. Рассмотрим его по шагам:

  1. Сделаем резервную копию информационной базы (обязательно!).
  2. В Конфигураторе найдем нужный регистр сведений и изменим его имя (например, добавим в конец единицу).
  3. Выполним обновление конфигурации базы данных (F7). Платформа переименует таблицу в SQL.
  4. Снова изменим имя регистра на исходное и опять обновим конфигурацию.

В некоторых случаях (особенно при изменении ключевых полей или состава измерений) 1С может предложить пересоздать таблицу. Если же просто удалить объект из метаданных, обновить базу, а затем загрузить его обратно из файла конфигурации (cf), данные будут удалены физически при первом обновлении. Однако этот метод требует монопольного доступа и значительного времени на реструктуризацию всей базы.

Работа с индексами и итогами

Проанализируем ситуацию с индексами. При удалении 35 ГБ данных SQL Server тратит огромные ресурсы на обновление индексов таблицы. Чтобы ускорить процесс удаления через DELETE, мы можем применить следующую тактику:

  1. Отключение индексов: Переведем некластерные индексы таблицы регистра в состояние Disable.
  2. Удаление данных: Выполним очистку таблицы.
  3. Перестроение индексов: Выполним Rebuild для всех индексов.

Это значительно снизит нагрузку на дисковую подсистему и сократит время выполнения операции.

Завершающие действия после удаления

После того как данные удалены (особенно если использовался TRUNCATE или прямые SQL-запросы), необходимо выполнить «гигиенические» процедуры:

Резюме: Для удаления 35 ГБ данных оптимальным является либо использование TRUNCATE TABLE в SQL (самый быстрый путь), либо программное удаление порциями через регистраторы (самый надежный путь для сохранения логики 1С). Выбор зависит от вашей квалификации в работе с SQL и критичности простоя системы.

← На главную