Журнал транзакций базы 1С занял весь диск: как сжать LDF и не допустить повторного роста

· 10 мин

Содержание

Чтобы уменьшить файл .ldf базы 1С в SQL Server, сначала освободите место внутри журнала транзакций, а потом сожмите сам файл командой DBCC SHRINKFILE. Освободить журнал можно двумя путями: перевести базу в модель восстановления SIMPLE или сделать резервную копию журнала (BACKUP LOG) и остаться в FULL.

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

СпособКогда выбиратьЧто теряете
SIMPLE + сжатиеНебольшая фирма, полная копия раз в сутки устраиваетВосстановление на точку во времени
BACKUP LOG + сжатие, остаётесь в FULLВажная база, нужна точка восстановления внутри дняНичего, но нужен регламент копий лога
Отключить базу и удалить LDFНикогдаРискуете получить неоткрываемую базу

Почему журнал транзакций базы 1С разрастается

SQL Server пишет в журнал каждое изменение данных: проведение документов, закрытие месяца , загрузку из банка, реструктуризацию при обновлении конфигурации. Место внутри журнала освобождается только при определённых условиях, и они зависят от модели восстановления.

Когда база 1С создаётся через консоль кластера или из окна запуска, SQL Server берёт параметры из системной базы model. У неё по умолчанию модель FULL. В итоге база работает в полной модели, а копии журнала никто не делает. Лог растёт без ограничений, пока не займёт диск.

Основные причины роста:

  • 📈 модель FULL или BULK_LOGGED без регулярного BACKUP LOG;
  • ⏳ долгая открытая транзакция: зависший сеанс, закрытие месяца на большой базе, обработка, которая меняет миллионы записей одной транзакцией;
  • 🔧 обновление конфигурации с реструктуризацией крупных таблиц;
  • 🧱 перестроение индексов в плане обслуживания: операция полностью журналируется в модели FULL;
  • 🔁 репликация, зеркалирование или группы доступности, которые ещё не забрали записи из лога.

Если журнал уже в несколько раз больше файла данных .mdf, почти наверняка это первая причина: полная модель без копий журнала.

Как проверить, чем занят журнал и сколько в нём свободно

Не начинайте со сжатия. Сначала выясните, что держит лог, иначе команда отработает без результата.

Откройте SQL Server Management Studio, подключитесь к серверу и выполните запрос в окне New Query. Узнаём размер журнала и процент заполнения по всем базам:

DBCC SQLPERF(LOGSPACE);

В результате колонки Log Size (MB) и Log Space Used (%). Если файл занимает 80 ГБ, а заполнен на 3%, место внутри уже свободно и остаётся только сжать файл. Если заполнен на 95%, сначала нужно освободить журнал.

Теперь главный вопрос: что мешает освобождению. Подставьте имя своей базы:

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

Колонка log_reuse_wait_desc прямо называет причину:

ЗначениеЧто означаетЧто делать
NOTHINGЖурнал ничем не удерживаетсяМожно сжимать
LOG_BACKUPЖдёт резервной копии журналаBACKUP LOG или перевод в SIMPLE
ACTIVE_TRANSACTIONОткрыта долгая транзакцияНайти её через DBCC OPENTRAN
CHECKPOINTНе было контрольной точкиВыполнить CHECKPOINT
REPLICATION, AVAILABILITY_REPLICAЛог ждёт репликуРазбираться с репликацией, не сжимать вслепую

Логическое имя файла журнала понадобится для сжатия. Оно часто не совпадает с именем файла на диске:

USE [buh_base];
SELECT name, physical_name, size * 8 / 1024 AS size_mb
FROM sys.database_files
WHERE type_desc = N'LOG';

Колонка size хранится в страницах по 8 КБ, поэтому умножаем на 8 и делим на 1024, получаем мегабайты.

Быстрое решение: модель SIMPLE и сжатие файла LDF

Этот вариант освобождает диск за пару минут. Пользователей выгонять из 1С не нужно, сервер 1С останавливать тоже. Но в часы нагрузки сжатие идёт медленнее, поэтому лучше выбрать время, когда в базе мало работы.

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

Порядок действий:

  1. Сделайте полную копию базы: в SSMS правой кнопкой по базе, Tasks → Back Up..., тип Full.
  2. Переведите базу в простую модель и выполните контрольную точку.
  3. Сожмите файл журнала до разумного размера.
  4. Проверьте результат через DBCC SQLPERF(LOGSPACE).

Скрипт целиком (замените buh_base и buh_base_log на свои имена из запроса выше):

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

Число 1024 — целевой размер в мегабайтах. Не сжимайте журнал до 1 МБ: при первой же крупной операции он снова начнёт расти небольшими приращениями, и это замедлит работу 1С.

Сколько оставить, ориентируйтесь так: примерно 10–25% от размера файла данных, но не меньше 1 ГБ. Для базы на 40 ГБ это 4–10 ГБ.

В модели SIMPLE журнал тоже может вырасти, если идёт одна огромная транзакция. Например, закрытие года на крупной базе. Модель освобождает лог после контрольной точки, но не может освободить записи ещё открытой транзакции.

Через графический интерфейс то же делается так: свойства базы, страница Options, поле Recovery model = Simple. Затем правой кнопкой по базе Tasks → Shrink → Files, тип файла Log, режим Reorganize pages before releasing unused space с указанием целевого размера.

Сжатие журнала без смены модели восстановления

Если база должна остаться в FULL, освобождайте журнал резервной копией лога. После неё неактивная часть журнала становится доступной для повторного использования, и файл можно сжать.

BACKUP LOG [buh_base]
TO DISK = N'D:\Backup\buh_base_log.trn';
GO
USE [buh_base];
DBCC SHRINKFILE (N'buh_base_log', 4096);
GO

С первого раза файл часто уменьшается не до конца. Причина в том, что активная часть журнала находится в конце файла, а SQL Server отрезает только хвост. Сделайте ещё одну копию журнала и повторите сжатие. Обычно хватает двух-трёх циклов.

Если база была в SIMPLE и вы возвращаете её в FULL, сразу после переключения сделайте полную копию. Пока её нет, BACKUP LOG вернёт ошибку, а журнал будет вести себя как в простой модели.

Копию лога можно делать в файл NUL, чтобы просто освободить журнал без записи на диск. Работает, но этим вы ломаете цепочку копий так же, как переходом в SIMPLE. Если так делать, то честнее перейти в простую модель.

Регулярное резервное копирование журнала, чтобы LDF не рос снова

Сжатие — разовая мера. Если оставить полную модель без копий лога, через месяц-два диск закончится снова.

Выберите один вариант и закрепите его в регламенте:

  • 🟢 Модель SIMPLE + полная копия каждую ночь. Самый простой режим для небольших баз. При сбое теряется работа с момента последней копии.
  • 🟡 Модель FULL + полная копия ночью + копия журнала каждые 15–60 минут. Можно восстановиться на любую минуту. Размер журнала держится в пределах объёма изменений за интервал.
  • 🔵 Дифференциальные копии в течение дня добавляют к любому из вариантов, когда база большая и полная копия идёт долго.

Пример: база 60 ГБ, за час пользователи генерируют около 300 МБ записей в журнал. При копии лога раз в 30 минут ему хватит 1–2 ГБ даже с запасом на закрытие месяца. Без копий те же 300 МБ в час дадут примерно 7 ГБ в сутки, около 200 ГБ за месяц.

Проверьте и настройку роста файла. Прирост в процентах для журнала плох: чем больше файл, тем крупнее каждый скачок. Поставьте фиксированный шаг:

ALTER DATABASE [buh_base]
MODIFY FILE (NAME = N'buh_base_log', FILEGROWTH = 512MB);

Слишком мелкий шаг (1 МБ, 10 МБ) тоже вреден. Журнал дробится на тысячи виртуальных сегментов (VLF), из-за этого медленнее идёт восстановление и запуск базы. Количество сегментов в SQL Server 2016 SP2 и новее смотрят так:

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

Если сегментов несколько тысяч, сожмите журнал до минимума и одним шагом увеличьте до нужного размера командой ALTER DATABASE ... MODIFY FILE (... SIZE = 4096MB).

Регламент для журнала базы 1С
Выполнено: 0 / 6

Автоматизация обслуживания и контроль места на диске

В редакциях Standard и Enterprise есть SQL Server Agent и планы обслуживания. В SSMS откройте Management → Maintenance Plans, создайте план через мастер и добавьте задачи Back Up Database (Full) и Back Up Database (Transaction Log) с разным расписанием. Туда же добавьте задачу очистки старых файлов копий, иначе место закончится уже на диске резервных копий.

В редакции Express агента нет. Копии запускают через Планировщик заданий Windows и утилиту sqlcmd. Пример bat-файла для копии журнала:

@echo off
set DT=%date:~6,4%%date:~3,2%%date:~0,2%_%time:~0,2%%time:~3,2%
set DT=%DT: =0%
sqlcmd -S .\SQLEXPRESS -E -Q "BACKUP LOG [buh_base] TO DISK = N'D:\Backup\buh_base_%DT%.trn'"

Разбор даты в bat зависит от региональных настроек Windows. Проверьте, какое имя файла получается на вашем сервере, прежде чем ставить задание в расписание. Учтите и ограничение Express: размер файла данных одной базы не больше 10 ГБ, журнал в этот лимит не входит.

Не включайте в планах обслуживания задачу Shrink Database и параметр AUTO_SHRINK. Регулярное сжатие бесполезно: журнал снова растёт, сервер тратит ресурсы на приращения, а сжатие файла данных фрагментирует индексы.

Для контроля места:

  • 📊 раз в неделю смотрите DBCC SQLPERF(LOGSPACE) или отчёт Disk Usage в SSMS (правой кнопкой по базе, Reports → Standard Reports);
  • 🔔 настройте оповещение SQL Server Agent на ошибку 9002 — это ошибка переполнения журнала;
  • 💾 держите журналы на отдельном томе, чтобы рост лога не останавливал систему и файлы данных.

Ошибка 9002 в 1С обычно видна пользователям как отказ при записи документа с текстом от СУБД: The transaction log for database 'buh_base' is full due to 'LOG_BACKUP'. В конце сообщения та же причина, что в log_reuse_wait_desc.

Если файл журнала не уменьшается

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

Чего делать нельзя: отключать базу (Detach), удалять LDF и подключать .mdf без журнала. Если база была закрыта некорректно, SQL Server не сможет восстановить согласованность без лога, и база перейдёт в состояние SUSPECT или RECOVERY_PENDING. Восстанавливать её придётся из копии.

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

Нужно ли выгонять пользователей из 1С на время сжатия журнала?
Нет. Смена модели восстановления, контрольная точка и DBCC SHRINKFILE выполняются при работающих пользователях. Сеансы 1С не обрываются, но в часы пик операция идёт медленнее.
Можно ли сделать то же самое выгрузкой в .dt из Конфигуратора?
Можно пересоздать базу через выгрузку и загрузку информационной базы, но это долго и требует монопольного доступа. Для журнала транзакций это избыточно: сжатие средствами SQL Server решает задачу без остановки работы.
Влияет ли модель SIMPLE на скорость работы 1С?
Заметно нет. Объём записи в журнал почти тот же, меняется только момент освобождения места. Разница в восстановлении: в SIMPLE откатиться можно только к последней полной или дифференциальной копии.
Почему журнал вырос, хотя база в SIMPLE?
Чаще всего из-за одной большой транзакции: реструктуризация при обновлении конфигурации, закрытие месяца, перепроведение документов за год. После её завершения место освободится, файл можно сжать.
Что делать с журналом базы tempdb?
Файлы tempdb пересоздаются при перезапуске службы SQL Server, и их размер возвращается к заданному в настройках. Перезапуск оборвёт все сеансы 1С, поэтому делайте его только вне рабочего времени.