При работе с крупными серверными базами данных (объемом от 100 ГБ и выше) стандартные механизмы отбора и пометки документов на удаление часто приводят к зависанию системы. Попытка единовременно обработать массив данных за несколько лет вызывает блокировки таблиц в MS SQL Server и переполнение журнала транзакций. Проанализируем основные причины этой проблемы и рассмотрим эффективные варианты её решения.
Прежде чем выбирать алгоритм работы, разберем по шагам, почему база 1С прекращает откликаться при массовых манипуляциях с документами:
FULL) любые изменения, отмена проведения документов и удаление движений фиксируются в журнале транзакций. Файл `.ldf` начинает разрастаться, упираясь в скорость дисковой подсистемы.ПередЗаписью и ПриЗаписи. Это влечет за собой пересчеты, дополнительные проверки и высокую нагрузку на процессор.Основной технический подход при работе с миллионами записей — работа небольшими порциями (пачками) внутри транзакций. Оптимальный размер порции составляет от 500 до 2000 документов.
Для максимально быстрой записи необходимо отключать обработчики событий объекта с помощью флага ОбменДанными.Загрузка = Истина. При этом важно помнить, что если документ был проведен, перед установкой пометки его движения в регистрах нужно очистить явно.
Рассмотрим пример кода для обработки документов порциями:
Выборка = Запросы.ПолучитьДокументыЗаПериод(ДатаНачала, ДатаОкончания);
Счетчик = 0;
НачатьТранзакцию();
Пока Выборка.Следующий() Цикл
ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
// Отключаем встроенные проверки и обработчики событий
ДокОбъект.ОбменДанными.Загрузка = Истина;
// Явно очищаем движения проведенного документа
Для Каждого НаборЗаписей Из ДокОбъект.Движения Цикл
НаборЗаписей.Очистить();
НаборЗаписей.Записать();
КонецЦикла;
// Устанавливаем пометку удаления
ДокОбъект.УстановитьПометкуУдаления(Истина, Ложь);
Счетчик = Счетчик + 1;
// Фиксируем транзакцию каждые 1000 документов
Если Счетчик % 1000 = 0 Тогда
ЗафиксироватьТранзакцию();
НачатьТранзакцию();
КонецЕсли;
КонецЦикла;
Если ТранзакцияАктивна() Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Чтобы ускорить процесс записи и исключить технические сбои серверной инфраструктуры, перед запуском процедуры выполнения необходимо произвести настройку среды:
FULL на SIMPLE. Это предотвратит неуправляемый рост файла `.ldf`. После окончания процедур верните режим обратно и сделайте полную резервную копию.Если задача состоит в свертке базы данных (оставить только последний год), самый чистый и правильный архитектурный путь — не удалять гигабайты старых данных из текущей базы, а перенести нужные данные в пустую.
Рассмотрим алгоритм этого подхода:
COMConnector из рабочей базы в новую переносятся только справочники.Этот метод полностью исключает необходимость фрагментации и очистки таблиц базы объемом 100 ГБ, а новая база сразу работает с максимальной производительностью.
По завершении операций удаления или пометки документов данные в таблицах СУБД оказываются сильно фрагментированными. Чтобы вернуть скорость работы базы на прежний уровень, выполните регламентные работы на сервере MS SQL:
UPDATE STATISTICS для всех таблиц базы данных.REBUILD INDEX).MDF/LDF на диске не уменьшится автоматически. Для освобождения дискового пространства выполните операцию SHRINKDATABASE.