При работе с высоконагруженными системами на базе 1С:Предприятие часто возникает ситуация, когда технические регистры сведений (например, логи, история версий или кэш расчетов) разрастаются до огромных размеров. В рассматриваемом случае объем данных составляет 35 ГБ (оценить распределение места можно через SQL Базомер (8.2, 8.3)). Попытка очистить такой регистр «в лоб» через стандартные инструменты платформы или простую запись пустого набора записей часто приводит к переполнению tempdb, разрастанию лога транзакций (LDF-файла) и последующему переходу базы данных в режим восстановления (Recovery). Разберем по шагам, как решить эту задачу эффективно и безопасно.
Когда мы выполняем команду Набор.Записать() для очистки всего регистра, платформа 1С открывает одну гигантскую транзакцию. SQL Server вынужден фиксировать удаление каждой строки в логе транзакций, чтобы иметь возможность откатить изменения в случае сбоя. При объеме в 35 ГБ объем метаданных об удалении может превысить свободное место на диске, что приводит к остановке сервера. Проанализируем ситуацию: для успешной очистки нам нужно либо разбить операцию на мелкие части, либо использовать инструменты SQL, которые минимизируют логирование.
Это самый безопасный метод с точки зрения логики платформы, так как он учитывает все механизмы объектной техники 1С. Основная идея — не удалять всё сразу, а фиксировать изменения небольшими порциями. Рассмотрим реализацию для разных типов регистров.
Для независимого регистра сведений, если данных очень много, лучше всего использовать удаление и обработку записей по фильтрам (например, по определенным измерениям, периоду или по конкретным узлам обмена). Однако, если нужно очистить всё, можно воспользоваться следующим алгоритмом:
Набор = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
Набор.ОбменДанными.Загрузка = Истина; // Отключаем лишние подписки и проверки
// Если регистр позволяет, устанавливаем отбор по какому-либо критерию (например, по дате)
// И выполняем запись пустого набора для этой порции
Набор.Записать();
Если регистр подчинен регистратору, удаление происходит через очистку движений документов. Разберем пример кода, который выбирает регистраторы и очищает их движения порциями, чтобы не перегружать tempdb:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Т.Регистратор КАК Регистратор
|ИЗ
| РегистрСведений.ИмяВашегоРегистра КАК Т";
Выборка = Запрос.Выполнить().Выбрать();
Набор = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
Набор.ОбменДанными.Загрузка = Истина;
Пока Выборка.Следующий() Цикл
Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
Набор.Записать(); // Каждая итерация — отдельная транзакция
КонецЦикла;
Важный момент: использование ОбменДанными.Загрузка = Истина критически важно, так как это предотвращает срабатывание тяжелых обработчиков событий «ПриЗаписи», которые могут замедлить процесс в десятки раз.
Если база данных находится на SQL Server и вам нужно очистить регистр полностью, самым быстрым способом будет команда TRUNCATE TABLE. В отличие от DELETE, эта команда не записывает удаление каждой строки в лог транзакций, а просто освобождает страницы памяти, занятые таблицей.
Рассмотрим последовательность действий:
ПолучитьСтруктуруХраненияБазыДанных() или специализированные обработки для просмотра структуры БД. Таблица будет иметь имя вида _InfoRgXXXX.
-- Будьте крайне осторожны! Данные удаляются мгновенно и безвозвратно.
TRUNCATE TABLE _InfoRg12345; -- Замените на ваше имя таблицы
Преимущества: операция выполняется практически мгновенно, tempdb и лог транзакций не растут. Риски: 1С может «не заметить» удаления данных на уровне кэша сервера приложений. После выполнения операции рекомендуется перезапустить службу кластера 1С.
Если вы все же решили использовать DELETE через SQL или удаление средствами 1С, проанализируем настройки самой базы данных. Если база находится в режиме Full Recovery Model, каждое удаление 35 ГБ данных будет порождать записи в логе аналогичного объема.
Выясним, как ускорить процесс:
Это позволит SQL Server не накапливать историю изменений в LDF-файле, а зацикливать его использование, что предотвратит нехватку места на диске.
Существует «хитрый» способ очистки данных штатными средствами, который иногда работает быстрее программного удаления. Рассмотрим его по шагам:
В некоторых случаях (особенно при изменении ключевых полей или состава измерений) 1С может предложить пересоздать таблицу. Если же просто удалить объект из метаданных, обновить базу, а затем загрузить его обратно из файла конфигурации (cf), данные будут удалены физически при первом обновлении. Однако этот метод требует монопольного доступа и значительного времени на реструктуризацию всей базы.
Проанализируем ситуацию с индексами. При удалении 35 ГБ данных SQL Server тратит огромные ресурсы на обновление индексов таблицы. Чтобы ускорить процесс удаления через DELETE, мы можем применить следующую тактику:
Disable.Rebuild для всех индексов.Это значительно снизит нагрузку на дисковую подсистему и сократит время выполнения операции.
После того как данные удалены (особенно если использовался TRUNCATE или прямые SQL-запросы), необходимо выполнить «гигиенические» процедуры:
UPDATE STATISTICS _InfoRgXXXX, чтобы планировщик запросов SQL понимал, что таблица теперь пуста.1C:Enterprise Server или удаление содержимого папки snccntxt решит эту проблему.SHRINKFILE для базы данных.Резюме: Для удаления 35 ГБ данных оптимальным является либо использование TRUNCATE TABLE в SQL (самый быстрый путь), либо программное удаление порциями через регистраторы (самый надежный путь для сохранения логики 1С). Выбор зависит от вашей квалификации в работе с SQL и критичности простоя системы.