Почему после переключения базы в полную модель восстановления замедляется запись и как это исправить?

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

Переход с простой модели восстановления (Simple) на полную (Full) в MS SQL Server — это стандартный шаг для обеспечения сохранности данных и возможности восстановления системы на любой момент времени. Однако многие администраторы и разработчики сталкиваются с неприятным сюрпризом: операции записи, которые раньше выполнялись мгновенно, начинают «тормозить», а пользователи жалуются на общую деградацию производительности. Разберем подробно, почему это происходит, как механизмы SQL Server влияют на 1С и что нужно настроить, чтобы вернуть былую скорость.

Разница в механизмах записи лога транзакций

Для начала проанализируем, в чем заключается фундаментальное различие между моделями восстановления с точки зрения дисковой активности. В любой модели все изменения (INSERT, UPDATE, DELETE) сначала записываются в лог транзакций (файл .LDF), и только потом — в файл данных (.MDF). Это обеспечивает принцип ACID.

В простой модели (Simple) SQL Server автоматически очищает пространство внутри лога после каждого контрольного сегмента (checkpoint), который происходит довольно часто. Это означает, что файл лога практически не растет, так как старые записи затираются новыми. Место внутри файла переиспользуется циклично.

В полной модели (Full) ситуация иная. Записи в логе не могут быть перезаписаны до тех пор, пока не будет сделан бэкап лога транзакций (Transaction Log Backup). Лог становится «непрерывной лентой» событий. Если вы запустили массивную обработку, которая записывает 500 000 записей в РегистрСведений, лог будет расти до тех пор, пока не вместит всю информацию об этой огромной транзакции или пока не сработает регламентный бэкап.

Проблема первая: Частое авторасширение и фрагментация VLF

Одной из главных причин замедления является процесс выделения нового места под файл лога. Рассмотрим ситуацию: у вас установлен автоприрост лога по 1 Мб или 10%. При массовой записи SQL Server вынужден постоянно обращаться к операционной системе с запросом: «Дай мне еще 1 Мб». В этот момент все транзакции, ожидающие записи в лог, приостанавливаются.

Кроме того, каждое такое расширение создает внутри файла так называемые виртуальные лог-файлы (VLF). Если автоприрост маленький, количество VLF может достигать десятков тысяч. Проанализируем последствия: SQL Server тратит значительные ресурсы на управление огромным количеством мелких VLF, что замедляет не только запись, но и старт базы данных, а также процессы восстановления.

Рекомендация: Установите фиксированный и достаточно большой размер автоприроста. Для баз 1С среднего размера оптимальным будет значение 512 Мб или 1024 Мб. Это позволит серверу реже отвлекаться на физическое расширение файла.

Проблема вторая: Отсутствие мгновенной инициализации файлов для лога

Выясним важный технический нюанс. В SQL Server существует функция Instant File Initialization, которая позволяет мгновенно выделять место под файлы базы данных, не заполняя его нулями. Однако эта функция работает только для файлов данных (.MDF). Для лога транзакций (.LDF) она не применяется по соображениям безопасности.

Это означает, что каждый раз, когда лог прирастает, SQL Server физически записывает нули на диск в новое выделенное пространство. Если дисковая подсистема медленная или перегружена, это создает огромные очереди (Disk Queue) и блокирует работу 1С. Именно поэтому в полной модели так критична скорость последовательной записи на диске, где лежит лог.

Проблема третья: Достижение лимита размера файла

В процессе обсуждения часто выясняется, что для файла лога установлен «потолок» (Maximum Size). Когда лог достигает этого предела, SQL Server больше не может записывать новые транзакции. Он начинает судорожно пытаться найти место внутри файла, которое уже было сохранено бэкапом, или просто выдает ошибку.

Посмотрим на ситуацию, описанную в сообщениях: лог вырос и достиг максимального размера. В этот момент производительность падает практически до нуля. Не устанавливайте жестких ограничений, если в этом нет критической необходимости. Лучше настроить мониторинг свободного места на диске.

Проблема четвертая: Влияние на TempDB и Snapshot Isolation

Для платформы 1С 8.3 крайне рекомендуется использование режима Read Committed Snapshot Isolation (RCSI). В этом режиме версии строк хранятся в базе TempDB. При массовой записи в полной модели нагрузка на TempDB возрастает, так как сервер должен поддерживать версионность для всех параллельно работающих пользователей.

Если TempDB настроен некорректно (например, имеет слишком маленький автоприрост в 64 Мб, как упоминалось в обсуждении), это становится еще одним «бутылочным горлышком». Разберем, как оптимизировать TempDB:

  1. Вынесите TempDB на самый быстрый диск (NVMe/SSD).
  2. Установите количество файлов TempDB равным количеству ядер процессора (но не более 8).
  3. Установите фиксированный размер автоприроста (например, 512 Мб).

Оптимизация кода 1С при работе в полной модели

Проанализируем, как программист может помочь системе. Если мы используем МенеджерЗаписи для вставки 500 000 строк, каждая запись может трактоваться как отдельная транзакция (если не обернуть их в общую), либо как одна гигантская транзакция.

Длительные транзакции в полной модели — это «зло». Пока транзакция не завершена, место в логе, которое она занимает, не может быть освобождено даже бэкапом. Посмотрим на пример правильного подхода: разбиение на порции.


// Пример разбиения записи на порции для снижения нагрузки на лог
РазмерПорции = 1000;
Счетчик = 0;

Для Каждого СтрокаДанных Из ТаблицаДляЗаписи Цикл
    
    Если Счетчик = 0 Тогда
        НачатьТранзакцию();
    КонецЕсли;

    Менеджер = РегистрыСведений.МойРегистр.СоздатьМенеджерЗаписи();
    ЗаполнитьЗначенияСвойств(Менеджер, СтрокаДанных);
    Менеджер.Записать();
    
    Счетчик = Счетчик + 1;
    
    Если Счетчик >= РазмерПорции Тогда
        ЗафиксироватьТранзакцию();
        Счетчик = 0;
    КонецЕсли;

КонецЦикла;

Если Счетчик > 0 Тогда
    ЗафиксироватьТранзакцию();
EndIf;

Такой подход позволяет SQL Server освобождать место в логе между порциями (при условии частого бэкапа лога) и предотвращает его бесконтрольный рост.

Пошаговый алгоритм настройки производительности

  1. Проверка бэкапов: Убедитесь, что настроено регулярное копирование лога транзакций. Оптимальный интервал для активной базы 1С — каждые 10–15 минут.
  2. Настройка автоприроста: Замените прирост в процентах или мелкие значения в Мб на фиксированные 512 Мб или 1024 Мб для файлов .LDF и .MDF.
  3. Анализ VLF: Выполните SQL-запрос DBCC LOGINFO. Если количество строк (VLF) больше 1000, рекомендуется «сжать» лог (shrink) и заново вырастить его крупными кусками.
  4. Расположение файлов: В идеале файлы данных (.MDF) и файлы лога (.LDF) должны находиться на разных физических дисках. Лог требует высокой скорости последовательной записи.
  5. Отложенная надежность (Delayed Durability): Если бизнес готов к потере транзакций за последние 1-2 секунды в случае аварии, можно включить режим DELAYED_DURABILITY = FORCED. Это колоссально ускоряет запись в лог, так как подтверждение транзакции происходит до ее физического сброса на диск.

Подводя итог, можно сказать: сама по себе полная модель восстановления не является «тормозом». Замедление — это лишь симптом того, что настройки дисковой подсистемы и параметры файлов SQL Server не соответствуют объему генерируемых данных. Выполнив описанные выше рекомендации, вы добьетесь стабильной работы 1С при сохранении всех преимуществ Full Recovery Model.

← На главную