При администрировании баз данных 1С на SQL Server системные администраторы часто сталкиваются с ситуацией, когда размер резервной копии журнала транзакций (transaction log) оказывается сопоставим или даже превышает размер полной резервной копии всей базы данных. Это вызывает вопросы, особенно если полные бэкапы делаются ежедневно, а лог — каждые 30 минут. Давайте разберем эту ситуацию на примере работы с 1С:Розница и SQL Server 2017, выясним причины такого поведения системы и найдем эффективные способы оптимизации.
Для начала развеем популярный миф: полная резервная копия базы данных (Full Backup) не очищает и не усекает журнал транзакций в полной модели восстановления (Full Recovery Model). В этой модели единственный способ «пометить» пространство в логе как свободное для повторного использования — это сделать бэкап самого журнала транзакций (Log Backup).
Рассмотрим стандартную ситуацию. У нас есть база объемом 35 Гб. Мы делаем полный бэкап, после чего запускаем обслуживание индексов, а затем — бэкап лога. Если первый бэкап лога после «фулла» весит 15 Гб, это означает, что между моментом завершения полного бэкапа и моментом запуска бэкапа лога в базе было изменено или переписано данных именно на этот объем. В контексте 1С основным потребителем места в логе выступает операция INDEX REBUILD.
Основная причина взрывного роста журнала транзакций — это регламентное задание по перестроению индексов. Когда SQL Server выполняет REBUILD, он фактически создает новый индекс и удаляет старый. В полной модели восстановления каждая такая операция фиксируется в журнале транзакций. Если база данных интенсивно работает и индексы занимают значительную часть объема, их перестроение легко может сгенерировать десятки гигабайт записей в логе.
Проанализируем разницу между двумя методами обслуживания:
INDEX REORGANIZE), которая дефрагментирует существующие страницы индекса. Она протоколируется минимально и почти не вызывает роста бэкапа лога.Рекомендация: Пересмотрите свои скрипты обслуживания. Для баз 1С хорошей практикой считается использование адаптивных сценариев:
REORGANIZE.REBUILD.Это позволит избежать лишней нагрузки на лог там, где это не требуется.
Поскольку мы рассматриваем SQL Server 2017, нам доступна отличная функция — возобновляемое перестроение индексов (RESUMABLE INDEX REBUILD). Разберем, как это помогает контролировать размер лога. При обычном перестроении SQL Server вынужден держать транзакцию открытой до самого конца операции, что не дает журналу усекаться даже при частых бэкапах лога.
Если использовать RESUMABLE = ON, транзакция может фиксироваться частями. Это позволяет бэкапам лога, которые идут параллельно (например, каждые 30 минут), реально очищать уже обработанные части индекса из журнала, не дожидаясь окончания всего процесса. Пример команды:
ALTER INDEX ALL ON [ИмяТаблицы] REBUILD WITH (RESUMABLE = ON, MAX_DURATION = 120 MINUTES);
Если перестроение индексов необходимо выполнять в полном объеме, рассмотрим временное переключение базы данных в модель Bulk-Logged (с неполным протоколированием). В этом режиме операции по массовой вставке данных и перестроению индексов записываются в лог в минимальном объеме.
Алгоритм действий может быть следующим:
BULK_LOGGED.FULL.Внимание: Помните, что при нахождении базы в режиме Bulk-Logged вы теряете возможность восстановления «на точку во времени» (point-in-time) для транзакций, произошедших в этот период.
Рассмотрим ситуацию, упомянутую в обсуждении: файл лога раздут до 60 Гб, хотя данных в нем мало. Часто администраторы используют SHRINKFILE, чтобы уменьшить файл на диске. Однако постоянный цикл «рост файла — шринк» приводит к фрагментации самого файла лога на тысячи мелких виртуальных файлов (VLF).
Большое количество VLF (свыше 1000) значительно замедляет бэкап лога и процесс восстановления базы при сбоях. Выясним, как правильно настроить размер лога:
SHRINKFILE для журнала до минимального размера.Это позволит SQL Server создать несколько крупных и производительных VLF.
Если вы сделали бэкап лога, а место внутри файла не освободилось (и бэкап все равно большой), нужно выяснить, что удерживает транзакции. Проанализируем ситуацию с помощью системного запроса:
SELECT name, log_reuse_wait_desc
FROM sys.databases
WHERE name = 'ИмяВашейБазы';
Разберем основные значения log_reuse_wait_desc:
LOG_BACKUP: Лог ждет завершения бэкапа (самая частая причина).ACTIVE_TRANSACTION: Есть «зависшая» или очень долгая транзакция (например, фоновое задание 1С или необработанная транзакция обмена данными в Рознице).REPLICATION: Если настроена репликация, лог не очистится, пока данные не уйдут подписчикам.CHECKPOINT: База ожидает контрольной точки (выполните команду CHECKPOINT вручную для проверки).В распределенных информационных базах (РИБ), характерных для ритейла, часто активно работают таблицы регистрации изменений. При интенсивных обменах эти таблицы постоянно меняются. Если в плане обслуживания стоит жесткое перестроение индексов для всех таблиц подряд, это создает колоссальный поток данных в лог.
Проанализируем возможность исключения таблиц регистрации изменений (начинаются на _ChangeRec) из ежедневного REBUILD. Для них лучше использовать REORGANIZE, так как они постоянно находятся в динамике, и их перестроение дает лишь кратковременный эффект, заполняя при этом весь диск бэкапами лога.
REBUILD на скрипт с проверкой уровня фрагментации (например, популярный скрипт от Ola Hallengren или аналоги).RESUMABLE в SQL 2017+).SHRINK лога ежедневно. Пусть файл имеет стабильный размер, достаточный для прохождения регламентных работ без автороста.Соблюдение этих правил позволит вам сократить размер первого бэкапа журнала транзакций после обслуживания индексов в несколько раз и обеспечит стабильную работу системы 1С.