При администрировании баз данных 1С:Предприятия на MS SQL Server системные администраторы часто сталкиваются с ситуацией, когда файл журнала транзакций (.ldf) стремительно увеличивается и занимает все свободное дисковое пространство. Естественным первым желанием становится настройка автоматического сжатия (DBCC SHRINKFILE) в регламентных планах обслуживания. Однако регулярный шринк лога транзакций по расписанию считается грубой административной ошибкой, которая приводит к деградации производительности СУБД. Разберем детально, как устроен журнал транзакций, почему постоянное сжатие наносит вред системе и как решить проблему переполнения диска штатными методами.
Выясним причину, по которой сжатие файла .ldf по расписанию негативно влияет на работу пользователей 1С:
.mdf, .ndf). Для журнала транзакций (.ldf) по соображениям безопасности и архитектуры транзакционной целостности этот механизм не применяется. Каждый раз, когда после сжатия база данных требует расширения файла журнала, сервер физически забивает выделяемое пространство нулями на диске. В моменты интенсивной записи это приводит к зависанию пользовательских сессий, блокировкам и ошибкам по таймауту в 1С..ldf неизбежно вырастет обратно до того же объема. Регулярный шринк лишь заставляет дисковую подсистему выполнять бесполезную работу.В полной модели восстановления (Full Recovery Model) журнал транзакций не усекается автоматически после завершения транзакции. Место внутри лога помечается как свободное для повторной записи только после выполнения резервного копирования журнала транзакций (BACKUP LOG). Рассмотрим основные причины неконтролируемого роста:
Проанализируем состояние базы данных с помощью встроенных инструментов MS SQL Server. Чтобы понять, почему лог не освобождает пространство, выполним следующий запрос:
SELECT name, recovery_model_desc, log_reuse_wait_desc
FROM sys.databases
WHERE name = 'ИмяВашейБазы';
Посмотрим на поле log_reuse_wait_desc. Наиболее частые значения:
LOG_BACKUP — журнал ждет создания резервной копии лога транзакций. Это сигнал о том, что бэкапы лога делаются слишком редко или вообще отсутствуют.ACTIVE_TRANSACTION — усечение заблокировано долгой открытой транзакцией.CHECKPOINT — контрольная точка еще не успела сбросить грязные страницы на диск.NOTHING — пространство свободно для повторного циклического использования.Если запрос показал ACTIVE_TRANSACTION, найдем самую старую открытую транзакцию с помощью команды:
DBCC OPENTRAN('ИмяВашейБазы');
Команда вернет SPID (идентификатор сессии) и время старта транзакции. По этому идентификатору в мониторе активности или консоли администрирования 1С можно вычислить зависший сеанс или фоновое задание.
Основной способ остановить рост файла .ldf — сделать так, чтобы SQL Server циклически перезаписывал уже выделенные страницы внутри существующего файла. Для этого сократим интервал резервного копирования журнала транзакций. Оптимальным интервалом для рабочих баз 1С является от 5 до 15 минут (в периоды интенсивных регламентных операций — до 1–3 минут). При такой частоте бэкап отрабатывает за считанные секунды, а лог повторно использует внутреннее пространство и перестает раздувать физический размер файла.
Если файл журнала уже раздут до сотен гигабайт из-за разового сбоя или отсутствия бэкапов, выполним разовое приведение файла к рабочему объему:
log_reuse_wait_desc, что состояние равно NOTHING.DBCC SHRINKFILE.Пример команды для разового сжатия и выделения стабильного размера:
-- Разовое сжатие файла лога
DBCC SHRINKFILE (N'ИмяФайлаЛога_log' , 1024);
-- Задание фиксированного начального размера и фиксированного шага роста
ALTER DATABASE [ИмяВашейБазы]
MODIFY FILE ( NAME = N'ИмяФайлаЛога_log', SIZE = 10240MB , FILEGROWTH = 1024MB );
Разберем регламентные операции с индексами. Полное перестроение (Rebuild) в модели Full генерирует гигантский объем журнальных записей. Для уменьшения нагрузки рекомендуется:
Если в конфигурации выполняются самописные обработки загрузки данных или массовой обработки объектов, проверим программный код. Нельзя помещать обработку десятков тысяч документов в одну общую транзакцию. Массивные операции следует дробить на пакеты с фиксацией транзакций (например, порциями по 500–1000 элементов):
НачатьТранзакцию();
Счетчик = 0;
Для Каждого СтрокаТаблицы Из ДанныеДляЗагрузки Цикл
// Обработка данных
Счетчик = Счетчик + 1;
Если Счетчик % 1000 = 0 Тогда
ЗафиксироватьТранзакцию();
НачатьТранзакцию();
КонецЕсли;
КонецЦикла;
Если Счетчик % 1000 <> 0 Тогда
ЗафиксироватьТранзакцию();
КонецЕсли;
Такой подход позволяет бэкапу журнала освобождать обработанные VLF во время выполнения длительных операций, предотвращая лавинообразное разрастание файла .ldf.