При администрировании крупных баз данных «1С:Предприятие 8» на СУБД Microsoft SQL Server администраторы часто сталкиваются с проблемой лавинообразного роста файла журнала транзакций (файла с расширением .ldf). Ситуация может стать критической, когда размер лога начинает превышать размер самой базы данных (файла .mdf), блокируя работу пользователей и исчерпывая дисковое пространство сервера. Особенно удивляет администраторов то, что это происходит при настроенной простой (Simple) модели восстановления, при которой, казалось бы, лог должен очищаться автоматически.
В данной статье мы подробно разберем, почему растет лог транзакций в Simple-модели, как правильно выполнить его сжатие (Shrink) без вреда для производительности системы, а также рассмотрим оптимальные настройки СУБД для предотвращения подобных проблем в будущем.
Существует распространенное заблуждение, что при использовании простой модели восстановления (Simple Recovery Model) файл журнала транзакций вообще не должен увеличиваться в размерах. На самом деле это не так. СУБД SQL Server в любом случае записывает абсолютно все операции с данными в лог-файл для обеспечения транзакционной целостности (принципы ACID) и возможности отката незавершенных транзакций.
При простой модели автоматическое усечение (log truncation) действительно происходит после каждой контрольной точки (Checkpoint). Однако усекается исключительно неактивная часть лога. Если в системе выполняется длительная или «зависшая» транзакция, то вся область лога от начала этой транзакции до ее завершения считается активной. SQL Server физически не может усечь эту область, и файл лога вынужден увеличиваться на диске, чтобы записывать новые транзакции. Для диагностики подобных проблем можно использовать инструмент для анализа текущих запросов и блокировок на SQL-сервере.
Проанализируем основные причины удержания лога в активном состоянии при работе с 1С:
ПересчетИтоговРегистровНакопления, обновление конфигурации, реструктуризация таблиц или проведение крупных документов за длительный период. Платформа 1С выполняет эти процессы в рамках огромных транзакций, которые генерируют гигантские объемы данных в логе.Для того чтобы оперативно диагностировать причину, по которой лог транзакций не может усечься, выполним следующий системный запрос в SQL Server Management Studio (SSMS):
SELECT name, log_reuse_wait_desc
FROM sys.databases;
Проанализируем значение в колонке log_reuse_wait_desc для нашей проблемной базы данных:
Если мы обнаружили статус ACTIVE_TRANSACTION, выясним, какая именно сессия удерживает лог, с помощью системной команды:
DBCC OPENTRAN('Имя_Вашей_Базы_Данных');
Эта команда покажет нам идентификатор сессии (SPID). Используя системное представление, мы можем легко определить, какой пользователь или регламентный процесс 1С создал эту нагрузку:
SELECT
des.session_id,
des.login_name,
des.program_name,
des.host_name,
dest.text
FROM sys.dm_exec_sessions des
INNER JOIN sys.dm_exec_connections dec
ON des.session_id = dec.session_id
CROSS APPLY sys.dm_exec_sql_text(dec.most_recent_sql_handle) dest
WHERE des.session_id = [УКАЖИТЕ_SPID_ИЗ_DBCC_OPENTRAN];
Когда причина роста лога устранена (например, завершился пересчет итогов в 1С или была принудительно закрыта зависшая сессия), нам необходимо освободить неиспользуемое место на диске. Важно понимать разницу между терминами Truncate (усечение лога внутри файла — пометка блоков как свободных) и Shrink (физическое сжатие файла на диске).
Выполним процедуру безопасного сжатия файла журнала транзакций средствами SQL Server Management Studio по шагам:
Если вам привычнее использовать скрипты T-SQL, эту операцию можно быстро выполнить следующим кодом:
-- Переключение контекста на целевую базу данных
USE [Имя_Вашей_Базы_Данных];
GO
-- Сжатие лога транзакций базы до 1024 Мегабайт
-- Вместо 'Имя_Логического_Файла_Лога' укажите логическое имя из свойств базы данных
DBCC SHRINKFILE (N'Имя_Логического_Файла_Лога', 1024);
GO
Проанализируем технические нюансы, о которых часто забывают администраторы. Регулярно запускать операцию сжатия (Shrink) по расписанию в рабочей базе данных крайне не рекомендуется! Почему?
Физический файл журнала транзакций (.ldf) состоит из внутренних логических сегментов — Virtual Log Files (VLF). Когда мы сжимаем файл лога до минимального размера (например, до 1 МБ), а затем СУБД сталкивается с повседневными нагрузками 1С, файл лога начинает стремительно прирастать. Если шаг автоувеличения задан неверно (например, по умолчанию стоит 10% или мелкий шаг в несколько мегабайт), SQL Server при каждом расширении дискового пространства создает множество мелких VLF.
Такая ситуация называется фрагментацией VLF. Она приводит к следующим критическим последствиям:
Recovery при перезапуске службы SQL Server или примонтировании базы может длиться часами).Как поступить правильно? Сразу после экстренного сжатия лога задайте ему оптимальный начальный размер (Initial Size) и фиксированный шаг автоувеличения (Autogrowth). Не оставляйте лог сжатым до 1 МБ!
Рекомендуется установить начальный размер файла лога на уровне 10–15% от размера файла данных (например, для базы в 30 ГБ задайте логу начальный размер в 3 ГБ). Шаг автоувеличения настройте в мегабайтах, а не в процентах (например, фиксированными шагами по 512 МБ или 1024 МБ). Прирост большими блоками создает оптимальное количество VLF и убережет дисковую подсистему от лишней фрагментации.
Многие администраторы пытаются жестко ограничить рост файла лога в настройках автоувеличения (параметр Restrict Growth / Maxsize), надеясь защитить сервер от переполнения дисков. Посмотрим на риски этого подхода в среде 1С.
Если во время длительной регламентной операции 1С (например, обновление конфигурации метаданных или реструктуризация таблиц базы данных) размер лога достигнет установленного вами жесткого лимита, SQL Server незамедлительно аварийно прервет текущую транзакцию и выдаст ошибку 9002 (The transaction log for database is full). После этого начнется длительный и ресурсоемкий процесс отката транзакции (Rollback), который может парализовать работу всей компании на несколько часов, а в худшем случае — привести к логическому повреждению структуры базы данных из-за некорректно прерванного обновления.
Ограничивать максимальный размер лога допускается исключительно на тестовых и учебных серверах, но ни в коем случае не на рабочих базах данных 1С.
В процессе обсуждения обслуживания баз данных у администраторов часто возникает вопрос: почему база данных 1С в файле .mdf занимает 30 ГБ, резервная копия SQL (.bak) — около 15 ГБ, а выгрузка конфигурации в файл .dt — всего 4 ГБ? Выясним причину этой разницы:
.dt — это не физический бэкап. Это проприетарный логический архив платформы «1С:Предприятие 8». Он содержит сырые табличные данные, сжатые стандартными алгоритмами ZIP. При этом в файле .dt полностью отсутствуют индексы, статистика и зарезервированное под будущий рост базы свободное пространство. При загрузке .dt обратно в SQL СУБД будет вынуждена с нуля перестраивать все индексы, что создаст колоссальную нагрузку на диски и процессор..mdf — это рабочее тело базы данных. В нем хранятся сами данные таблиц, служебные структуры данных, индексы (которые в базах 1С нередко занимают до 40-50% общего объема файла) и свободное пространство для быстрого добавления новых записей (Slack space). Это сделано для обеспечения максимальной скорости чтения и записи информации на лету..bak с компрессией — физический снимок всех занятых страниц файла .mdf. Он включает в себя и данные, и индексы, поэтому восстанавливается на порядок быстрее, чем загружается файл .dt. За счет встроенных механизмов сжатия SQL Server его размер получается средним между .mdf и .dt.Для экономии дискового пространства и оптимизации работы сервера всегда отдавайте приоритет настройке планов обслуживания SQL Server (Maintenance Plans) с использованием нативного сжатия бэкапов, а не регулярной выгрузке файлов .dt. При необходимости можно воспользоваться пошаговой инструкцией по настройке регламентных операций MS SQL Server.