Как правильно управлять размером журнала транзакций в MS SQL Server при полной модели восстановления и почему не стоит делать шринк по расписанию

Системный администратор IT и автоматизация бизнеса
← На главную

При администрировании баз данных 1С:Предприятия на MS SQL Server системные администраторы часто сталкиваются с ситуацией, когда файл журнала транзакций (.ldf) стремительно увеличивается и занимает все свободное дисковое пространство. Естественным первым желанием становится настройка автоматического сжатия (DBCC SHRINKFILE) в регламентных планах обслуживания. Однако регулярный шринк лога транзакций по расписанию считается грубой административной ошибкой, которая приводит к деградации производительности СУБД. Разберем детально, как устроен журнал транзакций, почему постоянное сжатие наносит вред системе и как решить проблему переполнения диска штатными методами.

Почему регулярный шринк журнала транзакций вреден для базы данных

Выясним причину, по которой сжатие файла .ldf по расписанию негативно влияет на работу пользователей 1С:

  1. Отсутствие мгновенной инициализации файлов (Instant File Initialization). В MS SQL Server механизм быстрой инициализации файлов работает только для файлов данных (.mdf, .ndf). Для журнала транзакций (.ldf) по соображениям безопасности и архитектуры транзакционной целостности этот механизм не применяется. Каждый раз, когда после сжатия база данных требует расширения файла журнала, сервер физически забивает выделяемое пространство нулями на диске. В моменты интенсивной записи это приводит к зависанию пользовательских сессий, блокировкам и ошибкам по таймауту в 1С.
  2. Дробление на виртуальные файлы журнала (VLF). Внутри файла лога данные хранятся в виртуальных файлах журнала — Virtual Log Files (VLF). Постоянный цикл «сжатие до минимума — авторост при нагрузке» порождает тысячи мелких VLF. Избыточное количество VLF приводит к ощутимому замедлению фиксации транзакций, резкому увеличению времени запуска базы данных при перезапуске службы SQL Server и длительному восстановлению базы из резервных копий.
  3. Иллюзия освобождения места. Если бизнес-процессы 1С регулярно генерируют определенный объем журнальных записей (например, при проведении документов или регламентных заданиях), после сжатия файл .ldf неизбежно вырастет обратно до того же объема. Регулярный шринк лишь заставляет дисковую подсистему выполнять бесполезную работу.

Почему растет журнал транзакций в модели Full

В полной модели восстановления (Full Recovery Model) журнал транзакций не усекается автоматически после завершения транзакции. Место внутри лога помечается как свободное для повторной записи только после выполнения резервного копирования журнала транзакций (BACKUP LOG). Рассмотрим основные причины неконтролируемого роста:

  1. Слишком редкое создание бэкапов журнала транзакций. Интервал снятия бэкапа журнала один раз в час является недостаточным для активно используемых информационных баз 1С. Все изменения за этот час накапливаются в логе, заставляя файл физически расти.
  2. Длительные неделимые транзакции в коде 1С. Массивные групповые обработки, перепроведение документов, закрытие месяца или загрузка данных без периодической фиксации транзакций удерживают активный VLF. Пока транзакция открыта, ни один бэкап лога не сможет освободить место, занятое этой и последующими операциями.
  3. Тяжелое обслуживание индексов. Полное перестроение индексов (Index Rebuild) в модели Full генерирует колоссальный объем транзакционных записей, сопоставимый с размером самих таблиц данных.
  4. Зависшие клиентские сеансы и транзакции. Зависший сеанс 1С с открытой транзакцией блокирует усечение лога на неопределенный срок.

Диагностика: как узнать, что именно держит журнал транзакций

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


SELECT name, recovery_model_desc, log_reuse_wait_desc
FROM sys.databases
WHERE name = 'ИмяВашейБазы';

Посмотрим на поле log_reuse_wait_desc. Наиболее частые значения:

  1. LOG_BACKUP — журнал ждет создания резервной копии лога транзакций. Это сигнал о том, что бэкапы лога делаются слишком редко или вообще отсутствуют.
  2. ACTIVE_TRANSACTION — усечение заблокировано долгой открытой транзакцией.
  3. CHECKPOINT — контрольная точка еще не успела сбросить грязные страницы на диск.
  4. NOTHING — пространство свободно для повторного циклического использования.

Если запрос показал ACTIVE_TRANSACTION, найдем самую старую открытую транзакцию с помощью команды:

DBCC OPENTRAN('ИмяВашейБазы');

Команда вернет SPID (идентификатор сессии) и время старта транзакции. По этому идентификатору в мониторе активности или консоли администрирования 1С можно вычислить зависший сеанс или фоновое задание.

Пошаговое решение: как правильно стабилизировать размер лога

Шаг 1. Настройка частоты бэкапов журнала транзакций

Основной способ остановить рост файла .ldf — сделать так, чтобы SQL Server циклически перезаписывал уже выделенные страницы внутри существующего файла. Для этого сократим интервал резервного копирования журнала транзакций. Оптимальным интервалом для рабочих баз 1С является от 5 до 15 минут (в периоды интенсивных регламентных операций — до 1–3 минут). При такой частоте бэкап отрабатывает за считанные секунды, а лог повторно использует внутреннее пространство и перестает раздувать физический размер файла.

Шаг 2. Разовое сжатие и фиксация начального размера (преаллокация)

Если файл журнала уже раздут до сотен гигабайт из-за разового сбоя или отсутствия бэкапов, выполним разовое приведение файла к рабочему объему:

  1. Делаем бэкап журнала транзакций.
  2. Убеждаемся через log_reuse_wait_desc, что состояние равно NOTHING.
  3. Выполняем разовый шринк файла журнала через Management Studio или команду DBCC SHRINKFILE.
  4. Важнейшее действие: сразу после сжатия задаем файлу лога фиксированный базовый размер (например, 10–20 ГБ в зависимости от дневного оборота базы) и шаг автороста в мегабайтах (например, 512 МБ или 1024 МБ), категорически отключив рост в процентах.

Пример команды для разового сжатия и выделения стабильного размера:


-- Разовое сжатие файла лога
DBCC SHRINKFILE (N'ИмяФайлаЛога_log' , 1024);

-- Задание фиксированного начального размера и фиксированного шага роста
ALTER DATABASE [ИмяВашейБазы] 
MODIFY FILE ( NAME = N'ИмяФайлаЛога_log', SIZE = 10240MB , FILEGROWTH = 1024MB );

Шаг 3. Корректировка планов обслуживания индексов

Разберем регламентные операции с индексами. Полное перестроение (Rebuild) в модели Full генерирует гигантский объем журнальных записей. Для уменьшения нагрузки рекомендуется:

  1. Использовать реорганизацию (Reorganize) вместо полного перестроения там, где уровень фрагментации не превышает 30%. Реорганизация генерирует существенно меньше транзакционных данных.
  2. Если перестроение необходимо, планировать резервное копирование журнала транзакций непосредственно в процессе или сразу после завершения шага дефрагментации.

Шаг 4. Оптимизация тяжелых операций в 1С

Если в конфигурации выполняются самописные обработки загрузки данных или массовой обработки объектов, проверим программный код. Нельзя помещать обработку десятков тысяч документов в одну общую транзакцию. Массивные операции следует дробить на пакеты с фиксацией транзакций (например, порциями по 500–1000 элементов):


НачатьТранзакцию();
Счетчик = 0;
Для Каждого СтрокаТаблицы Из ДанныеДляЗагрузки Цикл
    // Обработка данных
    Счетчик = Счетчик + 1;
    Если Счетчик % 1000 = 0 Тогда
        ЗафиксироватьТранзакцию();
        НачатьТранзакцию();
    КонецЕсли;
КонецЦикла;
Если Счетчик % 1000 <> 0 Тогда
    ЗафиксироватьТранзакцию();
КонецЕсли;

Такой подход позволяет бэкапу журнала освобождать обработанные VLF во время выполнения длительных операций, предотвращая лавинообразное разрастание файла .ldf.

← На главную