Лог базы 1С на MS SQL съел диск: как его уменьшить и больше не допускать разрастания

· 11 мин

Содержание

Журнал транзакций базы 1С в SQL Server чистят в два действия: сначала освобождают место внутри файла (резервной копией журнала BACKUP LOG или переводом базы в простую модель восстановления), потом сжимают сам файл командой DBCC SHRINKFILE. Частая ошибка — сразу жать Shrink. Пока журнал не усечён, команда почти ничего не отдаёт, и файл .ldf остаётся на 100+ ГБ.

Второе заблуждение — что лог растёт «из-за 1С». Платформа просто пишет в базу. Размер журнала определяют настройки SQL Server: модель восстановления, наличие бэкапов журнала, шаг автоприроста. Их и разберём по порядку.

Всё ниже выполняется в SQL Server Management Studio (SSMS) под учётной записью с правами sysadmin или владельца базы. Пользователей 1С отключать не обязательно, но сжатие лучше делать вне рабочего времени: под нагрузкой оно идёт медленно и может не дать результата.

Шаг 1. Проверяем, сколько весят файлы базы и чем занят журнал

Сначала нужно понять, что именно раздулось. У базы 1С на SQL Server минимум два файла: данные (.mdf) и журнал (.ldf). Если велик .mdf — это другая история, чисткой лога её не решить.

Размер файлов и их логические имена (они понадобятся для Shrink) показывает запрос:

USE [buh_base];  -- имя базы 1С в SQL Server
SELECT name        AS logical_name,
       type_desc,
       physical_name,
       size * 8 / 1024                         AS size_mb,
       FILEPROPERTY(name, 'SpaceUsed') * 8 / 1024 AS used_mb
FROM sys.database_files;

Имя базы в SQL не всегда совпадает с именем в списке баз 1С. Посмотреть его можно в консоли администрирования серверов 1С: свойства информационной базы → поле «База данных».

Заполненность журналов по всем базам сервера сразу:

DBCC SQLPERF(LOGSPACE);

Как читать результат:

  • 📦 Файл журнала 80 ГБ, занято 99% — журнал не усекается. Shrink сейчас бесполезен, сначала ищем причину (шаг 2 и раздел о причинах).
  • 🟢 Файл 80 ГБ, занято 3% — место внутри уже свободно. Можно сразу сжимать (шаг 3).
  • 📈 Файл 2 ГБ, занято 60% — нормальная картина, трогать не нужно.

Главный диагностический запрос — почему SQL Server не может переиспользовать журнал:

SELECT name, recovery_model_desc, log_reuse_wait_desc
FROM sys.databases
WHERE name = 'buh_base';

Значение log_reuse_wait_desc прямо называет виновника. Его расшифровка — в разделе о причинах разрастания ниже.

Шаг 2. Какую модель восстановления выбрать для базы 1С

Модель восстановления задаёт, когда SQL Server освобождает место в журнале.

МодельКогда журнал усекаетсяЧто можно восстановитьКому подходит
Полная (FULL)Только после BACKUP LOGСостояние на любой момент между бэкапамиБазы, где потеря даже часа работы недопустима
Простая (SIMPLE)Автоматически на контрольных точкахТолько момент полного или разностного бэкапаБазы с ежедневной полной копией, тестовые и копии разработчиков
С неполным протоколированием (BULK_LOGGED)После BACKUP LOGКак полная, с оговоркамиДля 1С практически не применяется

Новые базы SQL Server создаёт по образцу системной базы model, а у неё по умолчанию полная модель. Поэтому база 1С, созданная через консоль кластера, почти всегда получает FULL. Если при этом никто не настроил резервное копирование журнала, лог растёт бесконечно — это самый частый сценарий.

Решение принимается так:

  • 🕐 Достаточно восстановиться на вчерашний вечер — переводите базу в SIMPLE и делайте ежедневный полный бэкап.
  • 💼 Нужна точка восстановления «за 15 минут до сбоя» — оставляйте FULL, но обязательно настраивайте BACKUP LOG по расписанию (раз в 15–60 минут).

Сменить модель можно в SSMS: свойства базы → страница «Параметры» → «Модель восстановления». Или запросом:

ALTER DATABASE [buh_base] SET RECOVERY SIMPLE;

Переход FULL → SIMPLE обрывает цепочку бэкапов журнала. Восстановиться на момент между старыми копиями журнала после этого уже нельзя. Сразу после возврата в FULL сделайте полную резервную копию, иначе новые бэкапы журнала не к чему будет применять.

Шаг 3. Как безопасно сжать журнал транзакций (Shrink)

Перед любыми действиями — полная резервная копия базы средствами SQL Server . Выгрузка .dt из Конфигуратора тоже годится как страховка, но для больших баз она долгая.

Вариант А: база остаётся в полной модели

  1. Сделайте резервную копию журнала. Это и есть усечение — после неё место внутри .ldf помечается свободным:
BACKUP LOG [buh_base]
TO DISK = N'D:\Backup\buh_base_log.trn'
WITH COMPRESSION;
  1. Сожмите файл журнала до целевого размера в мегабайтах. Логическое имя берите из запроса шага 1:
USE [buh_base];
DBCC SHRINKFILE (N'buh_base_log', 4096);  -- цель 4 ГБ
  1. Проверьте размер повторно через DBCC SQLPERF(LOGSPACE).

Если файл ужался слабо, повторите пару «BACKUP LOG → SHRINKFILE» ещё раз. Причина в том, что журнал делится на виртуальные сегменты (VLF), а сжать файл можно только с конца. Если активный сегмент оказался в хвосте файла, нужен ещё один цикл, чтобы запись ушла в начало.

WITH COMPRESSION есть не во всех редакциях SQL Server. Если команда выдаёт ошибку про сжатие, просто уберите этот параметр.

Вариант Б: база переводится в простую модель

Подходит, когда точное восстановление на момент не нужно, а место на диске нужно прямо сейчас:

ALTER DATABASE [buh_base] SET RECOVERY SIMPLE;
CHECKPOINT;
USE [buh_base];
DBCC SHRINKFILE (N'buh_base_log', 4096);

Если база должна остаться в FULL, верните модель и сразу сделайте полный бэкап:

ALTER DATABASE [buh_base] SET RECOVERY FULL;
BACKUP DATABASE [buh_base] TO DISK = N'D:\Backup\buh_base_full.bak' WITH COMPRESSION;

Какой размер оставлять

Не сжимайте журнал «в ноль». На следующей же крупной операции он снова вырастет, причём рывками по шагу автоприроста, и база будет подтормаживать в моменты расширения файла. Разумная цель — размер журнала за самый тяжёлый день или операцию: для базы БП на 20–50 ГБ это обычно 2–8 ГБ.

Шаг автоприроста задайте в мегабайтах, а не в процентах: свойства базы → «Файлы» → столбец «Автоувеличение». Для журнала типично 512–1024 МБ. Процентный прирост на большом файле даёт огромные скачки.

Чего делать нельзя

  • ❌ Удалять файл .ldf вручную или «отсоединить базу, удалить лог, присоединить заново». Если в журнале были незавершённые транзакции, база может не подняться или потеряет согласованность.
  • ❌ Сжимать файл данных .mdf вместе с журналом по привычке. DBCC SHRINKDATABASE и Shrink данных сильно фрагментируют индексы, 1С после этого работает медленнее.
  • ❌ Ставить Shrink журнала в ежедневное расписание. Цикл «вырос — сжали — вырос» только нагружает диск.

Шаг 4. Почему журнал разрастается снова: разбор по log_reuse_wait_desc

Сжали, а через неделю опять 100 ГБ — значит, причина не устранена. Ответ почти всегда в столбце log_reuse_wait_desc.

Диагностика: выберите симптом

Долгую транзакцию ищут так:

USE [buh_base];
DBCC OPENTRAN;

Команда покажет номер сеанса (SPID) и время начала самой старой транзакции. По номеру сеанса в sys.dm_exec_sessions видно имя компьютера и программу.

Принудительно завершать сеанс (KILL) — крайняя мера. Транзакция откатится, а откат большой операции длится столько же, сколько она шла. Пользователь потеряет несохранённую работу. Сначала выясните, что это за процесс, и предупредите людей.

Какие операции в 1С дают пиковый рост журнала

Даже при правильных настройках бывают всплески. Их полезно знать заранее, чтобы планировать место на диске:

  • 🔧 Обновление конфигурации с реструктуризацией таблиц. Платформа перестраивает таблицы, и всё это пишется в журнал.
  • 📅 Закрытие месяца и перепроведение документов за длительный период.
  • 🧹 Удаление помеченных объектов в большой базе, свёртка базы.
  • 🛠 Тестирование и исправление информационной базы с реиндексацией.
  • 🗂 Загрузка .dt в существующую базу на SQL Server.
  • ⚙️ Перестроение индексов в плане обслуживания SQL — одна из самых «тяжёлых» для журнала задач.

Для разовой операции вроде обновления конфигурации можно временно перевести базу в простую модель, а после неё вернуть FULL и сделать полный бэкап. Только помните про разрыв цепочки журнала.

Много виртуальных сегментов

Если журнал годами рос мелкими шагами, внутри него накапливаются тысячи виртуальных сегментов (VLF). Это замедляет запуск базы и восстановление. На SQL Server 2016 SP2 и новее их число показывает запрос:

SELECT COUNT(*) AS vlf_count
FROM sys.dm_db_log_info(DB_ID('buh_base'));

Несколько сотен — нормально, тысячи — повод один раз сжать журнал почти до минимума и сразу вырастить его до рабочего размера одной командой ALTER DATABASE … MODIFY FILE (NAME = …, SIZE = …).

Шаг 5. Автоматизация: план обслуживания вместо ручной чистки

Ручная чистка лога — признак того, что не настроено резервное копирование. Правильный результат — журнал, который сам держит постоянный размер.

В SSMS: «Управление» → «Планы обслуживания» → «Мастер планов обслуживания». Для базы 1С в полной модели обычно делают три задачи:

Задача планаТипПериодичность (ориентир)
Полная резервная копия базыПолнаяРаз в сутки, ночью
Резервная копия журналаЖурнал транзакцийКаждые 15–60 минут в рабочее время
Очистка старых файлов бэкапаОчистка после обслуживанияРаз в сутки, хранение 7–14 дней

Для базы в простой модели достаточно полной ежедневной копии (можно дополнить разностными в течение дня) и очистки старых файлов.

Задачу «Сжать базу данных» в план не добавляйте. Мастер её предлагает, но для баз 1С она вредна по причинам, описанным выше.

Планы обслуживания выполняет агент SQL Server (SQL Server Agent). В редакции Express агента нет. Там те же команды BACKUP DATABASE и BACKUP LOG записывают в .sql-файл и запускают через sqlcmd из Планировщика заданий Windows:

sqlcmd -S localhost -E -i "C:\Scripts\backup_log.sql" -o "C:\Scripts\backup_log.txt"

Ключ -E означает вход под учётной записью Windows, под которой работает задание. У неё должны быть права на резервное копирование базы.

Проверьте, что задания реально отрабатывают: в SSMS разверните «Агент SQL Server» → «Задания», правой кнопкой по заданию → «Просмотр журнала». План, который тихо падает месяц, — вторая по частоте причина раздутого лога.

Настройка обслуживания журнала
Выполнено: 0 / 6

Шаг 6. Журнал в Always On, кластерах и репликации

В отказоустойчивых конфигурациях действуют свои ограничения. Сюда же входит вопрос, который часто задают администраторы 1С: влияет ли кластер серверов 1С на журнал? Нет. Кластер 1С — это рабочие процессы платформы, журнал транзакций целиком в ведении SQL Server.

Группы доступности Always On

  • 🔒 База в группе доступности обязана быть в полной модели. Перевести её в SIMPLE, не выведя из группы, нельзя.
  • 🔁 Журнал усекается только после того, как его приняли все синхронизируемые реплики. Отстающая или отключённая реплика держит журнал — в log_reuse_wait_desc будет AVAILABILITY_REPLICA.
  • 💾 BACKUP LOG можно делать и на вторичной реплике, если так настроены предпочтения резервного копирования. Цепочка журнала общая для группы.
  • 📉 DBCC SHRINKFILE для журнала выполняют на основной реплике, уменьшение файла передаётся на вторичные.

Если реплика давно не работает и не нужна, её убирают из группы — тогда журнал освободится. Решение принимает администратор SQL, а не 1С.

Отказоустойчивый кластер SQL Server (FCI)

Здесь один экземпляр SQL Server и общий диск. Для журнала всё работает как на одиночном сервере: те же модели восстановления, те же команды.

Доставка журналов (Log Shipping)

На основном сервере журнал бэкапит задание доставки. Не делайте вручную дополнительный BACKUP LOG в другую папку — вторичный сервер не получит этот файл, и цепочка сломается. Если нужна внеплановая копия, используйте параметр COPY_ONLY. И не переводите базу в SIMPLE: доставка журналов перестанет работать.

Репликация

Для баз 1С транзакционная репликация средствами SQL Server встречается редко: обмен данными в 1С обычно делается через планы обмена платформы. Если же репликацию когда-то включали и бросили, журнал не усекается со статусом REPLICATION. Её нужно корректно удалить через SSMS (раздел «Репликация»), после этого журнал освобождается обычным путём.

Ошибки, на которых чаще всего спотыкаются

  • 🔁 Перевели в SIMPLE, сжали, вернули FULL — и забыли полный бэкап. Бэкапы журнала после этого падают с ошибкой, а лог снова растёт.
  • 📂 Сжимают не тот файл. В DBCC SHRINKFILE указывается логическое имя из sys.database_files, а не имя файла на диске.
  • 🗄 Выполняют Shrink, находясь в контексте master. Команда работает с файлами текущей базы, поэтому перед ней нужна строка USE [имя_базы].
  • 💽 Кладут бэкапы журнала на тот же диск, где лежит .ldf. Место освобождается в одном файле и тут же занимается другим.
  • 🚨 Ждут, пока закончится место. Когда журнал заполнен и расти некуда, SQL Server возвращает ошибку 9002, и 1С не может записать ни одного документа. Пользователи видят сообщение о том, что журнал транзакций для базы заполнен. Ставьте мониторинг свободного места на диске.

Частые вопросы

Можно ли чистить журнал, пока пользователи работают в 1С?
Да, BACKUP LOG и DBCC SHRINKFILE для журнала не требуют монопольного доступа. Но под нагрузкой сжатие может не дать результата, поэтому лучше делать это вечером.
Сколько должен весить нормальный журнал базы 1С?
Жёсткой нормы нет. Ориентир: журнал при регулярных бэкапах занимает от 5 до 25% размера файла данных и держится примерно на одном уровне. Постоянный рост — признак проблемы.
Потеряются ли данные 1С после сжатия журнала?
Нет. Подтверждённые транзакции уже записаны в файл данных. Теряется только возможность восстановиться на момент между бэкапами, если вы переводили базу в простую модель.
Почему DBCC SHRINKFILE выполнился, а файл не уменьшился?
Журнал ещё не усечён или активный виртуальный сегмент находится в конце файла. Проверьте log_reuse_wait_desc, сделайте ещё один BACKUP LOG и повторите сжатие.
Нужна ли чистка журнала для файловой базы 1С?
Нет. У файловой базы нет журнала транзакций SQL Server, всё хранится в одном файле 1Cv8.1CD. Эта процедура касается только клиент-серверных баз на MS SQL.