Нередко системные администраторы и разработчики сталкиваются с ситуацией: после проведения свертки базы или массового удаления документов за прошлые периоды размер файла базы данных (MDF) на диске не уменьшается ни на мегабайт, а файл журнала транзакций (LDF), наоборот, катастрофически разрастается. Проанализируем, почему сервер баз данных ведет себя подобным образом, как устроено внутреннее хранение данных и какие шаги необходимо предпринять для фактического освобождения дискового пространства.
Разберем фундаментальный принцип работы MS SQL Server с файлами на диске. В отличие от настольных СУБД (например, DBF-таблиц), клиент-серверная СУБД никогда автоматически не уменьшает выделенный размер файлов данных (MDF/NDF) при выполнении операций DELETE. Выясним причину такого поведения:
Ghost Cleanup Task постепенно освобождает страницы памяти.Рассмотрим причину стремительного роста файла журнала транзакций. Каждая операция удаления строки из таблицы документов, таблиц строк или связанных регистров подробно протоколируется в журнале транзакций. Если база работает в модели восстановления Full (Полная), журнал транзакций не очищается автоматически даже после успешного завершения операции. Он будет расти до тех пор, пока не будет выполнено резервное копирование лога (BACKUP LOG). Пока бэкап не сформирован, пространство внутри файла журнала не может использоваться повторно.
Обратим внимание на платформенную специфику 1С 7.7. При удалении документов очищаются записи в таблицах заголовков (DH*), таблицах табличных частей (DT*) и таблицах движений регистров (RA*). Однако в регистрах накопления и бухгалтерии существуют таблицы периодических итогов (RG*). В этих таблицах могут оставаться пустые строки с нулевыми остатками за закрытые периоды. Сами по себе они занимают место и продолжают храниться в базе до тех пор, пока не будет выполнена регламентная процедура обслуживания итогов средствами платформы.
Разберем по шагам, как оценить реальный объем свободного места внутри файлов и безопасно вернуть его операционной системе.
Шаг 1. Анализ распределения пространства через SSMS
Прежде чем выполнять какие-либо действия, выясним, сколько свободного места фактически находится внутри файлов базы данных. Для этого в среде SQL Server Management Studio (SSMS) нажимаем правой кнопкой мыши по интересующей базе данных, переходим в меню Отчеты (Reports) → Стандартные отчеты (Standard Reports) → Использование диска (Disk Usage). В сформированном отчете будет наглядно показано соотношение занятого пространства данными и незанятого свободного места внутри файла данных (MDF) и журнала транзакций (LDF).
Шаг 2. Обслуживание итогов средствами 1С
Перед работой на уровне СУБД очистим неактуальные данные из таблиц итогов на уровне самой платформы 1С:
Операции → Управление регистрами (или Управление бухгалтерскими итогами). Сдвигаем границу рассчитанных итогов на начало актуального периода, тем самым отсекая пустые интервалы удаленных лет.Администрирование → Тестирование и исправление ИБ. Обязательно активируем пункт «Пересчет итогов». Это позволит платформе физически удалить неиспользуемые нулевые строки в таблицах 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 не дал ощутимого уменьшения размера, выполняют сжатие с последующим обязательным перестроением индексов:
DBCC SHRINKFILE (ИмяФайлаДанных, ЖелаемыйРазмерВ_МБ);.
EXEC sp_MSforeachtable @command1="DBCC DBREINDEX ('?')";
GO
Важное предупреждение: перестроение индексов (REINDEX или ALTER INDEX REBUILD) требует свободного места внутри файла данных для создания новых страниц B-Tree. Поэтому после реиндексации размер файла данных немного увеличится. Всегда оставляйте в файле данных не менее 15–20% свободного места для исключения постоянного авторасширения.
Для баз на платформе 1С 7.7 классическим и наиболее надежным методом уменьшения объема после свертки является создание абсолютно новой, чистой информационной базы из исходной конфигурации (файла 1cv7.md). В эту базу стандартными обработками обмена данными переносятся только актуальные справочники и сформированные входящие остатки. Такой подход исключает накопление фрагментации, полностью избавляет от фантомных записей и гарантирует минимально возможный размер файлов СУБД.