Короткий ответ

Ошибка 9002 / «transaction log full» на Accounting лечится не shrink-ом первым движением, а ответом: какой recovery model, почему лог не обрезается (log_reuse_wait_desc), есть ли log backup в Full/Bulk-logged. В Full без регулярного BACKUP LOG файл растёт до упора диска. Сделайте log backup на том, где есть место, либо исправьте Autogrowth/диск. Simple — лог не для point-in-time; не переключайте прод 1С в Simple «чтобы не рос», пока не принят новый RPO.

Экземпляр MSSQLSERVER на SQL01, приложение SRV-1C.

Симптомы и как отличить

Типичная картина:

  • 1С: ошибка СУБД, запись невозможна;
  • диск тома LDF 0 свободных;
  • log_reuse_wait_desc = LOG_BACKUP.

Отличия:

waitСмыслНе делать
LOG_BACKUPнужен backup logshrink без backup
ACTIVE_TRANSACTIONдлинная транзакция 1Сshrink
AVAILABILITY_REPLICA / DATABASE_MIRRORINGкопия не забрала logрвать AG вслепую
ACTIVE_BACKUP_OR_RESTOREидёт backupждать
диск tempdbдругой файлTempDB

Возможные причины

  1. Full recovery, job log backup сломан (диск backup, права, Agent).
  2. Огромная реструктуризация/закрытие месяца без запаса по LDF.
  3. Autogrowth выключен или шаг крошечный на полном диске.
  4. Длинный сеанс 1С без commit.
  5. Репликация/AG не применяет log.
  6. Редко: checkpoint не идёт в Simple из-за другой wait.

Диагностика

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

SELECT name, type_desc, physical_name, size * 8 / 1024 AS size_mb,
       max_size, growth, is_percent_growth
FROM sys.master_files
WHERE database_id = DB_ID(N'Accounting') AND type_desc = N'LOG';

SELECT session_id, open_transaction_count, login_name, host_name, program_name
FROM sys.dm_exec_sessions
WHERE open_transaction_count > 0;

Последние backup:

SELECT TOP 10 type, backup_start_date, backup_finish_date, backup_size / 1024 / 1024 AS mb
FROM msdb.dbo.backupset
WHERE database_name = N'Accounting'
ORDER BY backup_finish_date DESC;

type = L должен быть свежий при Full.

Решение

Сценарий A. Full, LOG_BACKUP, место на backup-томе есть

BACKUP LOG [Accounting]
TO DISK = N'E:\SQLBackup\Accounting_log_emergency.trn'
WITH INIT, COMPRESSION, STATS = 10;

Путь свой. После успешного backup log SQL сможет переиспользовать виртуальные логи, если нет другой wait. 1С снова пишет.

Почините job Agent: backup не выполняется.

Сценарий B. Диск LDF полный, backup некуда

Нужен хоть какой-то том для .trn, даже временно. Расширить диск лога. Добавить второй log file на другой том — аварийный костыль, потом спланировать вынос.

ALTER DATABASE [Accounting]
ADD LOG FILE (
  NAME = Accounting_log2,
  FILENAME = N'F:\SQLLog\Accounting_log2.ldf',
  SIZE = 8192MB,
  FILEGROWTH = 1024MB
);

Только если F: реально свободен. Потом не забудьте политику файлов.

Сценарий C. ACTIVE_TRANSACTION

Найдите сеанс 1С, завершите штатно (сеанс). Backup log не обрежет часть с активной транзакцией.

Сценарий D. «Переведём в Simple»

Только как осознанная смена политики RPO (потеря point-in-time). После SIMPLE сделайте full backup заново, настройте регулярный full. Для бухгалтерии обычно нужен Full + log. См. резервирование SQL-базы 1С.

Сценарий E. Shrink после аварии

Когда диск освободили и wait = NOTHING, можно один раз уменьшить лишний хвост, оставив запас под пик 1С. Не до 1 МБ.

-- после нормализации, с запасом под рабочую нагрузку
-- DBCC SHRINKFILE (N'Accounting_log', 8192);

Контур Accounting: Full recovery и регламент 1С

Реструктуризация, закрытие месяца, пересчёт итогов и массовая загрузка из Excel раздувают log сильнее, чем день оперативной работы. Перед такими окнами: свежий full, проверка что log backup job жив, запас на томе LDF больше, чем обычно. Если job Agent падает в это время, 9002 накроет обновление.

Не путайте BACKUP LOG с BACKUP DATABASE. Full не заменяет log в Full recovery для обрезки неактивной части. После аварийного Accounting_log_emergency.trn верните нормальные имена с timestamp, положите emergency-файл в ту же политику retention: он часть цепочки, его нельзя удалить, пока не пройдёт следующий полный цикл, от которого вы умеете restore.

Если log_reuse_wait_desc = AVAILABILITY_REPLICA, чините AG, не Simple. Перевод в Simple разорвёт AG/log shipping. Для одиночного SQL01 без AG это не ваш wait.

Autogrowth лога в процентах на 80 ГБ LDF может попытаться вырастить 8 ГБ на диске, где 2 ГБ — мгновенный 9002. Поставьте FILEGROWTH в мегабайтах (512–2048 МБ типичный порядок, не догма) и MAXSIZE с запасом ниже «диск 0».

1С при 9002 сыплет ошибками СУБД на всех сеансах. После лечения не нужно перезапускать кластер: сеансы продолжат писать. Проверьте один документ. Если сеансы «мертвые» после долгого отказа — точечный terminate, не рестарт агента.

Как проверить, что проблема устранена

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

Проведение документа в 1С. Свободное место на томе LDF. Следующий штатный log backup в истории msdb зелёный.

Если не помогло

  • Сразу снова 9002 — job log не встал или транзакция жива.
  • Рост во время обновления 1С — запас диска на окно, не Simple «на час» без backup.
  • AG — смотрите синхронизацию, не только прод-узел.

Профилактика

  • Full + log backup по RPO (часто 15–60 мин для 1С).
  • Алерт 9002, место тома лога, log_reuse_wait_desc.
  • Autogrowth в МБ, не 1%.
  • Перед реструктуризацией — место и свежий full.
  • Не класть LDF на крошечный диск C:.

FAQ

Почему лог снова 100 ГБ к утру?

Не было log backup ночью или шла гигантская транзакция. Shrink без backup — качели.

Truncate log не через backup?

В Full штатный механизм — BACKUP LOG. Трюки с detach не используйте.

Bulk-logged чем лучше?

Для bulk-операций, не как замена log backup. Цепочка всё равно нужна.

1С «в простой модели» из коробки?

Зависит от того, как создали базу. Проверьте recovery_model_desc, не верьте слухам. Для клиент-серверной бухгалтерии обычно Full.

Можно ли сжать лог, пока 1С работает?

Shrink конкурирует с нагрузкой и часто бесполезен при LOG_BACKUP. Сначала backup log.