При сопровождении баз данных 1С:Предприятия под управлением Microsoft SQL Server администраторы нередко сталкиваются с ситуацией, когда файл журнала транзакций (с расширением .ldf) разрастается до сотен гигабайт и полностью исчерпывает свободное дисковое пространство. При этом регулярные бэкапы лога и команды сжатия (Shrink) могут не давать желаемого эффекта. Разберем по шагам, почему возникает эта проблема, как выявить истинную причину блокировки очистки лога и как корректно настроить обслуживание базы данных.
В модели восстановления FULL (полная модель) журнал транзакций очищается только после создания резервной копии лога. Однако если файл продолжает непрерывно расти, значит, SQL Server не может повторно использовать освободившееся пространство. Проанализируем системное состояние базы с помощью простого запроса:
SELECT name, recovery_model_desc, log_reuse_wait_desc
FROM sys.databases
WHERE name = 'Имя_Вашей_Базы';
Посмотрим на значение в колонке log_reuse_wait_desc. Именно оно указывает на источник проблемы:
SIMPLE).Если диагностика показала наличие активной транзакции, выполним команду проверки открытых транзакций:
DBCC OPENTRAN;
Эта команда возвратит идентификатор сессии (SPID) и время запуска самой старой активной транзакции. Также детальные сведения можно получить через динамические административные представления:
SELECT
r.session_id,
s.login_name,
s.host_name,
r.start_time,
r.status,
t.text
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s ON r.session_id = s.session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t;
Выясним, как связать полученный идентификатор session_id с конкретным сеансом 1С, чтобы безопасно завершить зависшую операцию. Откроем утилиту «Консоль кластера серверов 1С:Предприятия», перейдем в ветку нужной информационной базы и откроем список «Соединения». В колонке «Номер соединения СУБД» (или «Идентификатор соединения СУБД») найдем число, в точности совпадающее с нашим session_id. Завершим проблемный сеанс штатно со стороны сервера 1С, чтобы не повредить кэш и корректно освободить блокировки.
Частыми виновниками долгих транзакций в 1С являются:
НачатьТранзакцию(). Пока диалог открыт на экране пользователя, транзакция висит и держит весь журнал.Для предотвращения зависания пользовательских подключений настроим в консоли кластера 1С свойства информационной базы: установим параметры «Время засыпания пассивного сеанса» и «Время завершения спящего сеанса».
Рассмотрим распространенную ошибку архитектуры обслуживания базы, когда ежедневно запускаются подряд Reorganize Index и Shrink Database. Такой регламент порождает замкнутый круг:
REORGANIZE) полностью построчно протоколируется в транзакционном журнале. Это генерирует гигантский объем записей и заставляет файл .ldf расти лавинообразно.Shrink Database принудительно переносит страницы данных с конца файла в начало, чтобы освободить место. При этом перемещении физический порядок страниц нарушается, что приводит к фрагментации индексов практически до 100%.Исключим операцию Shrink Database из регулярных планов обслуживания. Сжатие файлов базы данных допустимо исключительно как разовая ручная операция после глобальных чисток или переноса массивов информации.
Иногда системные администраторы пытаются перед ночным обслуживанием перевести базу в простую модель восстановления (SET RECOVERY SIMPLE), а после переиндексации вернуть ее в FULL. Проанализируем последствия такого шага: в момент переключения в простую модель цепочка бэкапов журнала транзакций безвозвратно прерывается. Когда база возвращается в режим FULL, регулярные бэкапы лога не смогут очищать журнал до тех пор, пока не будет снят полный бэкап базы данных (Full Backup). До этого момента лог продолжит расти без возможности усечения.
Если требуется оптимизировать ночной рост лога при обслуживании индексов, заменим операцию REORGANIZE на полное перестроение (REBUILD) и временно переключим модель восстановления на неполное протоколирование (BULK_LOGGED):
ALTER DATABASE [Имя_Базы] SET RECOVERY BULK_LOGGED;
-- Выполняем перестроение индексов: ALTER INDEX ... REBUILD
ALTER DATABASE [Имя_Базы] SET RECOVERY FULL;
В режиме BULK_LOGGED операция REBUILD протоколируется минимально, объем журнала не увеличивается лавинообразно, а цепочка резервных копий журнала сохраняется целостной.
Каждый файл журнала транзакций состоит из множества виртуальных файлов — VLF (Virtual Log Files). Если журнал постоянно растет мелкими порциями и часто сжимается, количество VLF может превысить несколько тысяч. Это приводит к сильным задержкам при фиксации транзакций и замедляет подъем базы при старте службы. Проверим структуру лога командой:
DBCC LOGINFO;
Количество строк в результате запроса показывает число VLF. Оптимальное количество должно находиться в диапазоне от нескольких десятков до пары сотен. Чтобы исправить фрагментацию VLF и предотвратить дальнейший неконтролируемый рост, выполним правильную последовательность действий:
BACKUP LOG [Имя_Базы] TO DISK = 'D:\Backup\log_backup.trn';
DBCC SHRINKFILE (Имя_Логического_Файла_Лога, 1024);
ALTER DATABASE [Имя_Базы]
MODIFY FILE (NAME = Имя_Логического_Файла_Лога, SIZE = 20480MB);