Почему не уменьшается размер базы MS SQL после удаления документов в 1С и как освободить место

Системный администратор 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

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

Механизм резервирования пространства в MS SQL Server

Разберем фундаментальный принцип работы MS SQL Server с файлами на диске. В отличие от настольных СУБД (например, DBF-таблиц), клиент-серверная СУБД никогда автоматически не уменьшает выделенный размер файлов данных (MDF/NDF) при выполнении операций DELETE. Выясним причину такого поведения:

  1. Резервирование под повторное использование: когда СУБД запрашивает у операционной системы пространство на диске, она закрепляет его за собой. Удаление строк освобождает страницы данных внутри самого файла, но не отдает их операционной системе. Освободившиеся страницы помечаются как доступные для записи новых данных внутри базы.
  2. Защита производительности: операция расширения файла (Autogrowth) — ресурсоемкая процедура, требующая обращения к файловой системе Windows. Если бы сервер сжимал файл после каждого удаления и снова расширял его при вставке, производительность системы критически снизилась бы.
  3. Фантомные записи (Ghost Records): при удалении строки физически не стираются мгновенно. Они лишь помечаются как удаленные, после чего асинхронный системный фоновый процесс Ghost Cleanup Task постепенно освобождает страницы памяти.

Почему журнал транзакций (LDF) вырос после удаления

Рассмотрим причину стремительного роста файла журнала транзакций. Каждая операция удаления строки из таблицы документов, таблиц строк или связанных регистров подробно протоколируется в журнале транзакций. Если база работает в модели восстановления Full (Полная), журнал транзакций не очищается автоматически даже после успешного завершения операции. Он будет расти до тех пор, пока не будет выполнено резервное копирование лога (BACKUP LOG). Пока бэкап не сформирован, пространство внутри файла журнала не может использоваться повторно.

Особенности архитектуры регистров в 1С 7.7

Обратим внимание на платформенную специфику 1С 7.7. При удалении документов очищаются записи в таблицах заголовков (DH*), таблицах табличных частей (DT*) и таблицах движений регистров (RA*). Однако в регистрах накопления и бухгалтерии существуют таблицы периодических итогов (RG*). В этих таблицах могут оставаться пустые строки с нулевыми остатками за закрытые периоды. Сами по себе они занимают место и продолжают храниться в базе до тех пор, пока не будет выполнена регламентная процедура обслуживания итогов средствами платформы.

Пошаговый план освобождения дискового пространства

Разберем по шагам, как оценить реальный объем свободного места внутри файлов и безопасно вернуть его операционной системе.

Шаг 1. Анализ распределения пространства через SSMS

Прежде чем выполнять какие-либо действия, выясним, сколько свободного места фактически находится внутри файлов базы данных. Для этого в среде SQL Server Management Studio (SSMS) нажимаем правой кнопкой мыши по интересующей базе данных, переходим в меню Отчеты (Reports) → Стандартные отчеты (Standard Reports) → Использование диска (Disk Usage). В сформированном отчете будет наглядно показано соотношение занятого пространства данными и незанятого свободного места внутри файла данных (MDF) и журнала транзакций (LDF).

Шаг 2. Обслуживание итогов средствами 1С

Перед работой на уровне СУБД очистим неактуальные данные из таблиц итогов на уровне самой платформы 1С:

  1. В режиме «1С:Предприятие» переходим в меню Операции → Управление регистрами (или Управление бухгалтерскими итогами). Сдвигаем границу рассчитанных итогов на начало актуального периода, тем самым отсекая пустые интервалы удаленных лет.
  2. Запускаем базу в режиме «Конфигуратор», открываем меню Администрирование → Тестирование и исправление ИБ. Обязательно активируем пункт «Пересчет итогов». Это позволит платформе физически удалить неиспользуемые нулевые строки в таблицах RG*.

Шаг 3. Усечение и сжатие журнала транзакций

Для тестовой или архивной копии базы, где не требуется сохранение цепочки транзакций для восстановления на точку во времени (Point-in-time recovery), переведем модель восстановления в режим SIMPLE и сожмем файл журнала транзакций:


ALTER DATABASE [ИмяБазы] SET RECOVERY SIMPLE;
GO
DBCC SHRINKFILE (ИмяФайлаЛога, 100);
GO

В этой команде вместо ИмяФайлаЛога указывается логическое имя файла журнала (его можно увидеть в свойствах базы данных на вкладке Files), а параметр 100 задает желаемый размер файла журнала в мегабайтах.

Шаг 4. Безопасное освобождение места в файле данных

Проанализируем распространенную ошибку: выполнение команды DBCC SHRINKDATABASE или использование пункта контекстного меню SSMS Задачи → Сжать → База данных. Полное сжатие базы перемещает страницы данных из конца файла в его начало в произвольном порядке, что приводит к катастрофической фрагментации индексов (вплоть до 98–99%).

Рекомендуется использовать щадящий вариант усечения файла данных с ключом TRUNCATEONLY:


DBCC SHRINKFILE (ИмяФайлаДанных, TRUNCATEONLY);
GO

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

Если же освободившееся пространство распределено внутри файла неравномерно и простой TRUNCATEONLY не дал ощутимого уменьшения размера, выполняют сжатие с последующим обязательным перестроением индексов:

  1. Выполняем сжатие файла данных до целевого размера с помощью команды DBCC SHRINKFILE (ИмяФайлаДанных, ЖелаемыйРазмерВ_МБ);.
  2. Сразу после завершения процедуры выполняем перестроение индексов по всей базе данных, чтобы восстановить производительность операций поиска и проведения документов:

EXEC sp_MSforeachtable @command1="DBCC DBREINDEX ('?')";
GO

Важное предупреждение: перестроение индексов (REINDEX или ALTER INDEX REBUILD) требует свободного места внутри файла данных для создания новых страниц B-Tree. Поэтому после реиндексации размер файла данных немного увеличится. Всегда оставляйте в файле данных не менее 15–20% свободного места для исключения постоянного авторасширения.

Альтернативный вариант: перенос остатков в чистую базу

Для баз на платформе 1С 7.7 классическим и наиболее надежным методом уменьшения объема после свертки является создание абсолютно новой, чистой информационной базы из исходной конфигурации (файла 1cv7.md). В эту базу стандартными обработками обмена данными переносятся только актуальные справочники и сформированные входящие остатки. Такой подход исключает накопление фрагментации, полностью избавляет от фантомных записей и гарантирует минимально возможный размер файлов СУБД.

← На главную