Журнал транзакций базы 1С раздулся до сотен гигабайт: разбор причин и безопасное сжатие
Содержание
Чтобы уменьшить LDF файл базы 1С на SQL Server, сначала освободите место внутри журнала, а потом сожмите сам файл командой DBCC SHRINKFILE. В модели восстановления FULL место освобождает резервная копия журнала (BACKUP LOG), в модели SIMPLE — контрольная точка (CHECKPOINT). Пока журнал внутри занят, сжатие не даст ничего.
Типичная картина: утром бухгалтерия не может провести документы, 1С пишет об ошибке записи, а на диске D: ноль байт. Администратор находит файл buh_log.ldf на 180 ГБ при самой базе на 25 ГБ. Проблема решается за полчаса, а настройка, после которой логи больше не растут, — ещё за час.
Почему журнал транзакций 1С растёт без остановки
LDF — это журнал транзакций. В него SQL Server пишет каждое изменение данных до того, как оно попадёт в основной файл MDF. Проведение документа, закрытие месяца , обновление конфигурации , реструктуризация — всё проходит через журнал.
Сам по себе журнал не очищается. Место внутри него помечается свободным (усекается) только при определённом событии. Если события нет — файл растёт, пока не кончится диск.
Основные причины разрастания:
- 🔴 Модель
FULLбез резервного копирования журнала. Самый частый случай. Базу для 1С создали через консоль кластера или вручную, модель восстановления по умолчанию взялась из системной базыmodel— обычно этоFULL. Полные бэкапы делаются, аBACKUP LOG— никогда. Журнал хранит всю историю изменений с момента создания базы. - 🟠 Длинная открытая транзакция. Закрытие месяца, перепроведение за год, свёртка базы, загрузка большого обмена. Пока транзакция не завершена, журнал нельзя усечь ни в какой модели.
- 🟡 Массовые операции 1С. Обновление конфигурации с реструктуризацией таблиц, удаление помеченных объектов, пересчёт итогов. Разовые всплески на десятки гигабайт — нормально, если потом журнал усекается.
- 🔵 Обслуживание индексов. Перестроение индексов (
REBUILD) в моделиFULLполностью пишется в журнал. Еженедельный план, который перестраивает всё подряд, даёт объём журнала, сопоставимый с размером базы. - ⚪ Репликация, зеркалирование, группы доступности AlwaysOn. Журнал не усекается, пока изменения не переданы на вторую сторону. Если реплика отстала или отвалилась — лог растёт.
Сам SQL Server честно говорит, что мешает усечению. Не гадайте — посмотрите поле log_reuse_wait_desc (следующий раздел).
Диагностика: что держит журнал и сколько в нём свободно
Все запросы выполняются в SQL Server Management Studio (SSMS) под учётной записью с правами sysadmin или владельца базы. Имя базы ниже — buh, подставьте своё (оно совпадает с именем базы на SQL Server, указанным в консоли кластера 1С).
Шаг 1. Насколько заполнен журнал
DBCC SQLPERF(LOGSPACE);
Команда вернёт таблицу по всем базам: размер журнала в мегабайтах и процент занятого места. Два сценария:
- занято 2–10% при файле на 100 ГБ — журнал уже усечён, файл можно сжимать сразу;
- занято 95–99% — сначала нужно освободить место внутри, иначе
SHRINKFILEничего не сделает.
Шаг 2. Почему журнал не усекается
SELECT name, recovery_model_desc, log_reuse_wait_desc
FROM sys.databases
WHERE name = 'buh';
Расшифровка частых значений log_reuse_wait_desc:
| Значение | Что означает | Что делать |
|---|---|---|
NOTHING | Журнал свободен | Можно сжимать |
CHECKPOINT | Ждёт контрольной точки | Выполнить CHECKPOINT |
LOG_BACKUP | Модель FULL, ждёт бэкапа журнала | Сделать BACKUP LOG |
ACTIVE_TRANSACTION | Есть незавершённая транзакция | Найти и дождаться её завершения |
ACTIVE_BACKUP_OR_RESTORE | Идёт резервное копирование | Дождаться окончания |
REPLICATION | Ждёт агента репликации | Разобраться с публикацией |
AVAILABILITY_REPLICA | Реплика AlwaysOn не догнала | Проверить вторичную реплику |
Шаг 3. Кто держит открытую транзакцию
Если увидели ACTIVE_TRANSACTION:
USE buh;
DBCC OPENTRAN;
Команда покажет номер сеанса (SPID) и время начала самой старой транзакции. По SPID в Мониторе активности SSMS или через sys.dm_exec_sessions видно, с какого компьютера и от какого приложения пришёл запрос. Для сеансов 1С это обычно рабочий процесс rphost на сервере 1С.
Не завершайте такой сеанс командой KILL сразу. Если это закрытие месяца или обновление конфигурации, откат займёт столько же времени, сколько шла операция, а пользователь потеряет результат. Сначала выясните в консоли кластера 1С, чей это сеанс и что он делает.
Шаг 4. Логическое имя файла журнала
Для SHRINKFILE нужно не имя файла на диске, а логическое имя:
USE buh;
SELECT name, physical_name, type_desc, size * 8 / 1024 AS size_mb
FROM sys.database_files;
Строка с type_desc = LOG — ваш журнал. Часто логическое имя выглядит как buh_log.
Экстренное сжатие LDF файла: пошаговый порядок
Пользователей выгонять из 1С не нужно: сжатие журнала работает при подключённых сеансах. Но делайте его в спокойное время — не во время закрытия месяца или ночного обмена.
Вариант А. База в модели FULL и цепочка бэкапов нужна
Если у вас настроено восстановление на момент времени (или должно быть), цепочку журналов не рвём:
- Сделайте резервную копию журнала на диск, где есть место:
BACKUP LOG buh TO DISK = 'E:\Backup\buh_log_1.trn';
- Сожмите файл журнала до целевого размера в мегабайтах:
USE buh;
DBCC SHRINKFILE (buh_log, 2048);
- Если файл уменьшился слабо, повторите пару «бэкап журнала → сжатие» ещё раз. Причина — активная часть журнала оказалась в конце файла, а SQL Server отрезает только свободный хвост. После следующего бэкапа запись уходит в начало файла, и хвост освобождается.
Бэкап журнала на 150 ГБ потребует столько же свободного места на целевом диске (меньше при включённом сжатии бэкапа). Если места нет совсем — переходите к варианту Б.
Вариант Б. Точка-в-момент не нужна, достаточно ночного полного бэкапа
Для большинства баз 1С в небольших компаниях это честный выбор: восстанавливаться будут на ночную копию.
ALTER DATABASE buh SET RECOVERY SIMPLE;
GO
USE buh;
CHECKPOINT;
DBCC SHRINKFILE (buh_log, 2048);
GO
Если позже захотите вернуть модель FULL — переключите её обратно и сразу сделайте полный бэкап: без него цепочка журналов не начнётся и BACKUP LOG выдаст ошибку.
Вариант В. Диск заполнен полностью, база встала
Когда свободно ноль байт и даже бэкап журнала положить некуда:
- 🧹 освободите место на любом диске сервера (старые бэкапы, дампы, временные файлы) или подключите сетевую папку для
BACKUP LOG; - 🔀 если нет ни того, ни другого, переведите базу в
SIMPLEпо варианту Б — это не требует места на диске.
Встречается совет «сделать бэкап журнала в NUL» (BACKUP LOG buh TO DISK = 'NUL'). Это то же самое, что выбросить журнал: цепочка восстановления рвётся, а SQL Server считает, что копия есть. Переключение на SIMPLE честнее — по свойствам базы сразу видно, что точки-в-момент нет.
Какой размер оставлять
Не сжимайте журнал «в ноль» (DBCC SHRINKFILE (buh_log, 0) или до 1 МБ). Ночью закроется месяц или пройдёт регламентное задание, и журнал снова вырастет — мелкими приращениями и с задержками для пользователей.
Ориентир для базы 1С: журнал на 10–25% от размера MDF, но не меньше 1–2 ГБ. Для базы на 40 ГБ это 4–10 ГБ.
Сравнение способов сжатия журнала
| Способ | Когда подходит | Риски |
|---|---|---|
BACKUP LOG + SHRINKFILE | Модель FULL, нужна точка-в-момент | Нужно место под бэкап журнала |
Перевод в SIMPLE + SHRINKFILE | Хватает ночного полного бэкапа | Нельзя откатиться на минуту до сбоя |
Бэкап журнала в NUL | Не рекомендуется | Скрытый разрыв цепочки бэкапов |
| Сжатие через мастер в SSMS | Разовое действие без скриптов | Те же, что у команды, — это тот же SHRINKFILE |
| Отсоединение базы и удаление LDF | Никогда для рабочей базы | Риск потерять базу, если она была закрыта не чисто |
Мастер в SSMS: правой кнопкой по базе → Tasks → Shrink → Files (в русской версии Задачи → Сжать → Файлы), тип файла «Журнал», указать целевой размер. Внутри он выполняет ту же команду.
Модель восстановления, при которой лог не растёт бесконтрольно
Выбор модели — решение не администратора SQL, а владельца данных. Вопрос простой: сколько работы бухгалтерии можно потерять при сбое?
| Модель | Что можно восстановить | Нагрузка на администрирование |
|---|---|---|
SIMPLE | Только на момент последнего полного или разностного бэкапа | Минимальная: журнал усекается сам |
FULL | На любую минуту, если цепочка журналов цела | Нужен регулярный BACKUP LOG |
BULK_LOGGED | Почти как FULL, массовые операции пишутся компактно | Для 1С обычно не используется |
Практические варианты для 1С:
- 🏢 5–15 пользователей, ночной бэкап устраивает. Модель
SIMPLE, полный бэкап раз в сутки. Можно добавить разностный бэкап в обед. - 🏭 Активная торговля, потеря полдня недопустима. Модель
FULL, полный бэкап раз в сутки, журнал каждые 15–60 минут.
Проверить модель всех баз сервера сразу:
SELECT name, recovery_model_desc FROM sys.databases ORDER BY name;
Чтобы новые базы 1С, созданные из консоли кластера, сразу получали нужную модель, задайте её у системной базы model — SQL Server копирует её настройки в каждую новую базу:
ALTER DATABASE model SET RECOVERY SIMPLE;
Настройка прироста файла
Второй источник проблем — шаг автоприроста. Прирост в 10% для журнала на 100 ГБ — это скачок на 10 ГБ, во время которого запись в базу ждёт. Задайте фиксированный шаг:
ALTER DATABASE buh
MODIFY FILE (NAME = buh_log, SIZE = 4096MB, FILEGROWTH = 512MB);
SIZE здесь — новый размер файла: команда только увеличивает его, уменьшать надо через SHRINKFILE.
Автоматизация очистки логов через SQL Server Agent
Ручное сжатие — разовая мера. Регулярное обслуживание строится на бэкапах, а не на SHRINKFILE по расписанию.
Для модели FULL
Создайте задание агента (SQL Server Agent → Jobs → New Job) с шагом T-SQL и расписанием «каждые 30 минут в рабочее время»:
DECLARE @f nvarchar(260) =
N'E:\Backup\Log\buh_' +
FORMAT(GETDATE(), 'yyyyMMdd_HHmm') + N'.trn';
BACKUP LOG buh TO DISK = @f WITH COMPRESSION, CHECKSUM;
COMPRESSION поддерживается в редакции Standard и выше, начиная с SQL Server 2008 R2. В Express нет самого SQL Server Agent — там задание запускают Планировщиком заданий Windows через sqlcmd.
Отдельным шагом удаляйте старые файлы .trn: через задачу «Очистка после обслуживания» в плане обслуживания или скриптом PowerShell. Храните журналы как минимум до следующего полного бэкапа плюс запас.
Для модели SIMPLE
Отдельное задание для журнала не нужно: он усекается на каждой контрольной точке. Достаточно ежедневного полного бэкапа в плане обслуживания (Management → Maintenance Plans).
Чего не ставить в расписание
Не добавляйте DBCC SHRINKFILE и тем более SHRINKDATABASE в ежедневный план. Сжатие журнала по расписанию создаёт цикл «сжали → вырос → сжали», а сжатие файлов данных перемешивает страницы и ломает индексы, после чего 1С заметно медленнее строит отчёты.
Как сжатие журнала сказывается на скорости 1С
Сжатие само по себе проходит быстро и почти не мешает пользователям. Проблемы возникают позже — когда журнал снова растёт.
- ⏳ Обнуление при приросте. Файлы журнала SQL Server всегда заполняет нулями при увеличении. Мгновенная инициализация файлов (Instant File Initialization) на журнал не распространяется; исключение в SQL Server 2022 — приросты до 64 МБ. На время прироста запись в базу ждёт: пользователь видит «подвисание» при проведении.
- 🧩 Фрагментация на VLF. Внутри журнал делится на виртуальные файлы (VLF). Сотни приростов маленькими шагами дают тысячи VLF, и база дольше стартует после перезапуска службы, медленнее восстанавливается и бэкапится.
- 📈 Нагрузка при закрытии месяца. Если журнал урезан до 100 МБ, первая же тяжёлая операция выполняет десятки приростов подряд.
Проверить число VLF (SQL Server 2016 SP2 и новее):
SELECT COUNT(*) AS vlf_count
FROM sys.dm_db_log_info(DB_ID('buh'));
Несколько десятков — норма, тысячи — повод пересоздать журнал правильно: сжать его до минимума одной командой и сразу вырастить до рабочего размера одним-двумя шагами через ALTER DATABASE … MODIFY FILE (SIZE = …).
Журнал лучше держать на отдельном диске от файлов данных и бэкапов. Запись в LDF идёт последовательно, и быстрый SSD под журнал заметно ускоряет проведение документов в 1С.
Частые вопросы
Можно ли просто удалить LDF файл, если база 1С не запускается?
SIMPLE.Нужно ли останавливать сервер 1С или выгонять пользователей перед сжатием журнала?
BACKUP LOG, CHECKPOINT и SHRINKFILE для журнала работают при подключённых сеансах. Выберите время без закрытия месяца и обменов, чтобы не столкнуться с длинной транзакцией.Почему после SHRINKFILE размер файла почти не изменился?
CHECKPOINT в SIMPLE) и повторите сжатие. Если log_reuse_wait_desc показывает ACTIVE_TRANSACTION, дождитесь завершения операции.