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

Системный администратор 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет IT и автоматизация бизнеса
← На главную

При работе с крупными базами данных 1С:Предприятие на платформе MS SQL Server администраторы часто сталкиваются с парадоксальной ситуацией: после удаления значительного объема информации (например, 90% документов) физический размер файла базы данных .mdf не только не уменьшается, но и продолжает расти. Попытки стандартного сжатия через SQL Server Management Studio (SSMS) часто не дают желаемого результата, упираясь в «магические числа», ниже которых объем файла не опускается.

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

Почему база растет при удалении данных

Проанализируем ситуацию, когда пользователь удалил 90% документов, а база выросла с 30 Гб до 89 Гб. Это происходит по нескольким техническим причинам:

  1. Журналирование транзакций (LDF): При массовом удалении объектов средствами 1С (метод Удалить()) каждая операция фиксируется в журнале транзакций. Если база находится в модели восстановления FULL, файл лога будет расти до тех пор, пока не будет выполнен бэкап журнала. Даже при модели SIMPLE активная транзакция требует места в логе.
  2. Реструктуризация таблиц: При запуске процедуры «Тестирование и исправление» (ТИИ) с включенной галкой «Реструктуризация», 1С создает новые временные таблицы, переносит в них данные из старых и затем удаляет старые. В момент переноса в базе фактически существуют две копии данных. SQL Server резервирует место под эти операции в файле .mdf, и после удаления временных таблиц это место помечается как свободное внутри файла, но не возвращается операционной системе автоматически.
  3. Ghost Records (Записи-призраки): В SQL Server удаление строк не происходит мгновенно на физическом уровне. Строки помечаются как удаленные (ghosted), чтобы ускорить транзакцию. Их окончательной очисткой занимается фоновый процесс Ghost Cleanup. Пока он не завершит работу, страницы данных считаются занятыми.
  4. Версионность строк: Если в базе включен режим READ_COMMITTED_SNAPSHOT, SQL Server хранит версии строк для обеспечения конкурентного доступа, что также требует дополнительного места.

Разбираем проблему «магического числа» при сжатии

Рассмотрим ситуацию, когда стандартная операция Shrink (Сжать базу) доходит до определенного предела (например, 36 Гб) и отказывается сжимать файл дальше, даже если реальных данных там на 7 Гб. Выясним основные причины этого затыка:

Параметр Initial Size (Начальный размер): В свойствах базы данных на закладке «Файлы» (Files) у каждого файла есть параметр начального размера. SQL Server воспринимает это число как минимальный порог. Если там установлено 36 Гб, команда сжатия проигнорирует все, что ниже. Чтобы сжать файл сильнее, необходимо сначала вручную изменить это значение в свойствах файла на меньшее (например, 1024 Мб) и нажать «ОК».

Фрагментация и неперемещаемые страницы: Операция сжатия (Shrink) работает путем перемещения страниц данных из конца файла в свободные «дыры» в начале. Однако некоторые типы данных, особенно LOB (Large Objects), такие как картинки и файлы в справочнике ХранилищеДополнительнойИнформации (таблица _Reference99), могут сильно фрагментироваться. Если в самом конце файла находится страница, которую SQL не может переместить, процесс сжатия остановится на этом месте.

Пошаговый алгоритм уменьшения размера базы

Проанализируем последовательность действий, которая поможет максимально эффективно вернуть место операционной системе.

Шаг 1. Смена модели восстановления

Для разовых операций по очистке базы целесообразно временно перевести базу в режим SIMPLE. Это позволит автоматически очищать журнал транзакций и не даст файлу .ldf раздуваться до бесконечности.


USE [master];
ALTER DATABASE [Имя_Вашей_Базы] SET RECOVERY SIMPLE;

Шаг 2. Анализ распределения данных по таблицам

Прежде чем сжимать, нужно понять, что именно занимает место. В 1С часто огромный объем занимают не документы, а бинарные данные. Используем стандартный отчет SQL «Disk Usage by Top Tables» или запрос:


SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    (SUM(a.total_pages) * 8) / 1024 AS TotalSpaceMB, 
    (SUM(a.used_pages) * 8) / 1024 AS UsedSpaceMB, 
    (SUM(a.it_pages) * 8) / 1024 AS UnusedSpaceMB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.object_id AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id
GROUP BY 
    t.Name, s.Name, p.Rows
ORDER BY 
    TotalSpaceMB DESC;

Если таблица _Reference99 (Хранилище доп. информации) все еще занимает 6 Гб, значит, удаление документов не затронуло связанные с ними файлы. В 1С требуется запустить очистку ненужных файлов в самой конфигурации.

Шаг 3. Перестроение индексов (Rebuild)

После удаления 90% данных индексы становятся крайне «разреженными». В страницах много пустого места, но они распределены по всему файлу. Перестроение индексов «утрамбует» данные максимально плотно.

Важно: Перестроение индексов само по себе требует временного места, поэтому файл .mdf может еще немного подрасти перед тем, как мы его сожмем.


-- Пример для конкретной таблицы
ALTER INDEX ALL ON [_Reference99] REBUILD;

Шаг 4. Сжатие файла базы данных (Shrink)

Вместо использования графического интерфейса, который часто работает некорректно с параметрами, воспользуемся командой DBCC SHRINKFILE. Мы будем указывать логическое имя файла данных и целевой размер в мегабайтах.


-- Сначала узнаем логическое имя файла
EXEC sp_helpdb [Имя_Вашей_Базы];

-- Сжимаем файл данных до 5 Гб (5120 Мб)
DBCC SHRINKFILE (N'Имя_Файла_Data' , 5120);

Метод «Выгрузка-Загрузка .dt»: почему он работает лучше?

Рассмотрим, почему автор темы получил архив в 7 Гб, хотя SQL-база «застряла» на 36 Гб. Механизм выгрузки .dt в 1С полностью игнорирует физическую структуру хранения SQL. Он последовательно считывает только «живые» записи из таблиц. При загрузке .dt обратно в новую базу SQL:

  1. Таблицы создаются заново.
  2. Данные записываются максимально плотно, страница за страницей.
  3. Индексы строятся с нуля, без фрагментации.
  4. Отсутствуют Ghost Records и неиспользуемые зарезервированные страницы.

Поэтому для задач подготовки «куска базы» для разработки метод выгрузки-загрузки через .dt или через «Схему XML» является наиболее эффективным, несмотря на его «старомодность».

Резюме и рекомендации

Подводя итог нашему анализу, выделим главные правила управления размером базы при массовом удалении данных:

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

← На главную