Как исправить ошибку «The transaction log for database is full due to LOG_BACKUP» и сопутствующую ошибку 3023 при работе с 1С?

Системный администратор IT и автоматизация бизнеса
← На главную

Введение: суть проблемы и почему блокируется вход в 1С

При работе с базами данных 1С:Предприятие, развернутыми на СУБД Microsoft SQL Server, администраторы и разработчики часто сталкиваются с ситуацией, когда пользователи не могут войти в информационную базу. При этом система выдает критическую ошибку СУБД: Microsoft SQL Server Native Client 11.0: The transaction log for database 'Base_Name' is full due to 'LOG_BACKUP'. Эта ошибка означает, что файл лога транзакций (LDF) базы данных переполнен, и SQL Server заблокировал любые операции записи в базу до тех пор, пока не будет выполнен бэкап этого лога.

Попытки быстро решить проблему стандартными средствами СУБД (например, через попытку сжатия файла лога транзакций или перевода базы данных в простую модель восстановления Simple) часто натыкаются на еще одну неприятную ошибку: «Backup, file manipulation operations (such as ALTER DATABASE ADD FILE) and encryption changes on a database must be serialized. Reissue the statement after the current backup or file manipulation operation is completed» (Microsoft SQL Server, Error: 3023).

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

Почему возникает ошибка 3023 и что она означает?

Для начала проанализируем природу ошибки 3023. Ее текст прямо говорит о том, что операции резервного копирования и манипуляции с файлами базы данных должны выполняться последовательно (сериализованно). SQL Server накладывает жесткие внутренние блокировки при выполнении определенных процессов. Мы не можем одновременно выполнять:

В ситуации, с которой столкнулся автор темы на форуме, в фоновом режиме СУБД уже выполнялся (или завис) процесс резервного копирования лога транзакций. Поскольку лог-файл был физически переполнен, этот процесс бэкапа либо не мог завершиться из-за нехватки места, либо заблокировал сам себя. Любая последующая попытка администратора перевести базу в модель восстановления Simple или выполнить сжатие лога вручную вызывала ошибку 3023, так как СУБД ожидала завершения текущей фоновой операции бэкапа.

Быстрое, но опасное решение: Перезапуск службы SQL Server

В ходе обсуждения на форуме автор применил радикальный метод — перезапуск службы Microsoft SQL Server с помощью командной строки:


net stop mssqlserver
net start mssqlserver

Рассмотрим, почему этот метод сработал и какие риски он в себе несет. Принудительная остановка службы СУБД сбрасывает все активные фоновые процессы, включая зависший бэкап лога транзакций. После запуска службы база переходит в состояние восстановления (In Recovery), SQL Server накатывает незавершенные транзакции и откатывает те, что не были зафиксированы. После этого блокировка фонового бэкапа снимается, что позволяет на короткое время войти в базу и выполнить административные действия.

Внимание! Использовать этот метод на "живой" рабочей базе крайне не рекомендуется по следующим причинам:

  1. Принудительный перезапуск обрывает транзакции пользователей 1С «на полуслове», что может привести к логической несогласованности данных в базе 1С.
  2. Если в базе выполнялась длительная транзакция (например, проведение крупного документа или закрытие месяца), процесс ее отката (rollback) при старте службы может занять часы, в течение которых база будет полностью недоступна.
  3. Существует риск физического повреждения структуры файлов базы данных, если в момент остановки выполнялись критические дисковые операции записи.

Как решить проблему профессионально: точечное снятие блокировки

Вместо перезапуска всего сервера СУБД мы можем точечно выявить зависший процесс бэкапа и остановить только его. Давайте разберем этот процесс по шагам.

Шаг 1. Выявим идентификатор сессии (SPID), которая выполняет блокирующую операцию резервного копирования. Для этого запустим следующий SQL-запрос в SQL Server Management Studio (SSMS):


SELECT 
    r.session_id AS [SPID],
    r.command,
    t.text AS [Query],
    r.start_time,
    r.percent_complete,
    DATEADD(second, r.estimated_completion_time/1000, GETDATE()) AS [Estimated_Completion_Time]
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.command IN ('BACKUP DATABASE', 'BACKUP LOG', 'RESTORE DATABASE', 'RESTORE LOG');

Этот запрос вернет список всех текущих процессов резервного копирования и восстановления с указанием их SPID (идентификатора сессии), текста запроса и процента выполнения.

Шаг 2. Завершим зависший процесс бэкапа. Допустим, запрос показал, что бэкап лога выполняется под сессией номер 65. Выполним команду принудительного завершения именно этой сессии:

KILL 65;

Эта команда безопасно отменит только зависшую операцию бэкапа, не затрагивая других пользователей и службы SQL Server. Блокировка файлов будет снята, и ошибка 3023 исчезнет.

Диагностика причин переполнения лога транзакций

Просто снять блокировку — это лишь половина дела. Нам необходимо выяснить, почему файл лога транзакций LDF переполняется и почему SQL Server не может использовать его пространство повторно. Для этого выполним следующий диагностический запрос:

SELECT name, recovery_model_desc, log_reuse_wait_desc FROM sys.databases;

Особое внимание обратим на колонку log_reuse_wait_desc для нашей базы данных. Она указывает на причину, по которой лог не очищается автоматически. Разберем основные сценарии:

  1. LOG_BACKUP. Это наиболее частая причина для баз данных с полной моделью восстановления (FULL). SQL Server хранит все транзакции в лог-файле до тех пор, пока не будет сделан бэкап лога (BACKUP LOG). Если бэкапы лога не настроены или ломаются, файл LDF будет расти бесконечно, пока не займет весь диск.
  2. ACTIVE_TRANSACTION. В базе присутствует длительная или зависшая транзакция. В 1С это часто связано с зависшими фоновыми заданиями или незавершенными транзакциями пользователей. Найти "виновника" можно с помощью команды DBCC OPENTRAN.
  3. REPLICATION. Если настроена репликация баз данных, лог не очистится, пока транзакции не будут успешно отправлены на сервер-получатель.

Экстренное сжатие лога транзакций «в пустоту»

Если диск полностью переполнен, и у нас нет свободного места даже для того, чтобы записать стандартный бэкап лога, мы столкнемся с тупиковой ситуацией. В этом случае мы можем применить административный прием — выполнить резервное копирование лога на фиктивное устройство NUL (аналог «черной дыры» /dev/null):

BACKUP LOG [Base_Name] TO DISK = 'NUL';

Эта команда заставит SQL Server очистить виртуальный лог транзакций и пометить внутреннее пространство LDF-файла как свободное для повторного использования, при этом физический файл бэкапа создаваться не будет. После этого мы сможем без проблем выполнить сжатие файла лога до разумного размера с помощью команды:

DBCC SHRINKFILE (acc_main, 1024);

Здесь acc_main — логическое имя файла лога транзакций из настроек базы данных, а 1024 — желаемый размер файла в мегабайтах после сжатия. Обратите внимание! Сброс лога «в пустоту» прерывает цепочку бэкапов, необходимую для восстановления базы на определенный момент времени (Point-in-time recovery). Сразу же после выполнения этой процедуры обязательно сделайте полный бэкап всей базы данных!

Модели восстановления базы данных 1С: Simple против Full

В ходе обсуждения на форуме возник спор о том, какую модель восстановления (Recovery Model) лучше использовать для баз данных 1С:Предприятие. Рассмотрим подробнее аргументы обеих сторон.

Простая модель (Simple)

В этой модели лог транзакций очищается автоматически при фиксации транзакций и прохождении контрольной точки (checkpoint). Лог-файл LDF практически не разрастается, база требует минимум внимания со стороны администратора.

Полная модель (Full)

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

Как правильно настроить обслуживание базы 1С в полной модели

Если специфика бизнеса требует использования модели восстановления Full, мы должны правильно настроить регламентные задачи в SQL Server Agent. Ошибкой автора темы было то, что база находилась в модели Full, но регулярные бэкапы логов транзакций не выполнялись.

Правильный регламент обслуживания должен выглядеть следующим образом:

  1. Полный бэкап базы данных (Full Backup) — выполняется один раз в сутки (например, ночью в нерабочее время). Это основа нашей цепочки восстановления.
  2. Дифференциальный (разностный) бэкап (Differential Backup) — может выполняться несколько раз в день (например, каждые 4-6 часов). Он содержит только изменения, произошедшие с момента последнего полного бэкапа, что ускоряет процесс восстановления по сравнению с накатыванием сотен бэкапов логов.
  3. Бэкап лога транзакций (Transaction Log Backup) — выполняется регулярно в течение всего дня с высокой частотой (каждые 10, 15 или 30 минут в зависимости от требований бизнеса). Этот процесс сбрасывает накопленный лог транзакций, предотвращая разрастание файла LDF, и обеспечивает минимальную потерю данных при сбоях.

Для настройки этих задач мы можем использовать встроенные планы обслуживания (Maintenance Plans) в SSMS или написать собственные T-SQL скрипты для SQL Server Agent. При создании резервных копий сторонними средствами администрирования не забывайте использовать опцию COPY_ONLY, чтобы не нарушить основную цепочку резервного копирования, настроенную в СУБД.

Заключение

Подводя итоги, отметим, что ошибка переполнения лога СУБД LOG_BACKUP в базах 1С всегда является следствием отсутствия или неверной настройки политики резервного копирования. Перезапуск службы SQL Server — это лишь временный костыль, который может навредить целостности данных. Правильным решением является точечное завершение блокирующего бэкапа с помощью команды KILL, очистка лога и последующая грамотная настройка регламентных планов обслуживания в зависимости от выбранной модели восстановления базы данных.

← На главную