При работе с крупными базами данных 1С:Предприятие на платформе MS SQL Server администраторы часто сталкиваются с парадоксальной ситуацией: после удаления значительного объема информации (например, 90% документов) физический размер файла базы данных .mdf не только не уменьшается, но и продолжает расти. Попытки стандартного сжатия через SQL Server Management Studio (SSMS) часто не дают желаемого результата, упираясь в «магические числа», ниже которых объем файла не опускается.
В этой статье мы подробно разберем внутренние механизмы работы SQL Server и 1С, которые приводят к такому поведению, и составим пошаговый план действий по реальному освобождению дискового пространства.
Проанализируем ситуацию, когда пользователь удалил 90% документов, а база выросла с 30 Гб до 89 Гб. Это происходит по нескольким техническим причинам:
Удалить()) каждая операция фиксируется в журнале транзакций. Если база находится в модели восстановления FULL, файл лога будет расти до тех пор, пока не будет выполнен бэкап журнала. Даже при модели SIMPLE активная транзакция требует места в логе..mdf, и после удаления временных таблиц это место помечается как свободное внутри файла, но не возвращается операционной системе автоматически.Ghost Cleanup. Пока он не завершит работу, страницы данных считаются занятыми.READ_COMMITTED_SNAPSHOT, SQL Server хранит версии строк для обеспечения конкурентного доступа, что также требует дополнительного места.Рассмотрим ситуацию, когда стандартная операция Shrink (Сжать базу) доходит до определенного предела (например, 36 Гб) и отказывается сжимать файл дальше, даже если реальных данных там на 7 Гб. Выясним основные причины этого затыка:
Параметр Initial Size (Начальный размер): В свойствах базы данных на закладке «Файлы» (Files) у каждого файла есть параметр начального размера. SQL Server воспринимает это число как минимальный порог. Если там установлено 36 Гб, команда сжатия проигнорирует все, что ниже. Чтобы сжать файл сильнее, необходимо сначала вручную изменить это значение в свойствах файла на меньшее (например, 1024 Мб) и нажать «ОК».
Фрагментация и неперемещаемые страницы: Операция сжатия (Shrink) работает путем перемещения страниц данных из конца файла в свободные «дыры» в начале. Однако некоторые типы данных, особенно LOB (Large Objects), такие как картинки и файлы в справочнике ХранилищеДополнительнойИнформации (таблица _Reference99), могут сильно фрагментироваться. Если в самом конце файла находится страница, которую SQL не может переместить, процесс сжатия остановится на этом месте.
Проанализируем последовательность действий, которая поможет максимально эффективно вернуть место операционной системе.
Для разовых операций по очистке базы целесообразно временно перевести базу в режим SIMPLE. Это позволит автоматически очищать журнал транзакций и не даст файлу .ldf раздуваться до бесконечности.
USE [master];
ALTER DATABASE [Имя_Вашей_Базы] SET RECOVERY SIMPLE;
Прежде чем сжимать, нужно понять, что именно занимает место. В 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С требуется запустить очистку ненужных файлов в самой конфигурации.
После удаления 90% данных индексы становятся крайне «разреженными». В страницах много пустого места, но они распределены по всему файлу. Перестроение индексов «утрамбует» данные максимально плотно.
Важно: Перестроение индексов само по себе требует временного места, поэтому файл .mdf может еще немного подрасти перед тем, как мы его сожмем.
-- Пример для конкретной таблицы
ALTER INDEX ALL ON [_Reference99] REBUILD;
Вместо использования графического интерфейса, который часто работает некорректно с параметрами, воспользуемся командой DBCC SHRINKFILE. Мы будем указывать логическое имя файла данных и целевой размер в мегабайтах.
-- Сначала узнаем логическое имя файла
EXEC sp_helpdb [Имя_Вашей_Базы];
-- Сжимаем файл данных до 5 Гб (5120 Мб)
DBCC SHRINKFILE (N'Имя_Файла_Data' , 5120);
Рассмотрим, почему автор темы получил архив в 7 Гб, хотя SQL-база «застряла» на 36 Гб. Механизм выгрузки .dt в 1С полностью игнорирует физическую структуру хранения SQL. Он последовательно считывает только «живые» записи из таблиц. При загрузке .dt обратно в новую базу SQL:
Поэтому для задач подготовки «куска базы» для разработки метод выгрузки-загрузки через .dt или через «Схему XML» является наиболее эффективным, несмотря на его «старомодность».
Подводя итог нашему анализу, выделим главные правила управления размером базы при массовом удалении данных:
.mdf из-за создания копий таблиц.Если же ваша цель — получить компактную копию базы для разработки, самым быстрым и качественным способом будет создание новой чистой базы SQL и загрузка в нее данных через файл .dt.