При обслуживании больших информационных баз 1С на платформе MS SQL Server администраторы нередко сталкиваются со следующей ситуацией: после масштабной программной очистки старых периодов или свертки базы (например, удаления документов за прошлые годы) физический размер файла данных .mdf практически не изменяется, даже если была выполнена процедура сжатия (Shrink). При этом файл журнала транзакций .ldf может успешно усекаться, а основной файл базы данных продолжает занимать прежние десятки гигабайт. Разберем детально, почему так происходит и как правильно освободить дисковое пространство.
Проанализируем внутреннее устройство хранения данных в MS SQL Server и особенности платформы 1С:
Документ.Удалить(1) команда DELETE удаляет строки из таблиц, освобождая пространство внутри конкретных страниц. Однако сами страницы остаются привязанными к таблицам и индексам. Команда усечения не объединяет полупустые страницы автоматически, из-за чего общий объем выделенного таблицам пространства не уменьшается._1SJOURN), шапок (DH*), табличных частей (DT*) и движений регистров (RA*). Однако в таблицах итогов регистров (RG*) остаются строки с нулевыми остатками по закрытым периодам и удаленным измерениям. Пока не выполнено специальное сжатие итогов средствами платформы, эти записи физически занимают место.TRUNCATEONLY лишь отрезает нераспределенное свободное место в самом конце файла базы данных. Если в конце файла расположена хотя бы одна занятая страница данных или объект LOB/BLOB, сжатие хвоста файла останавливается.Первым делом необходимо навести порядок в таблицах итогов на уровне самой платформы 1С. Простого удаления документов недостаточно — нужно запустить регламентные процедуры платформы:
В процессе сжатия итогов платформа найдет в таблицах RG* все строки, где остатки по ресурсам равны нулю, и физически удалит их из базы. Это позволит очистить значительный объем записей, оставшихся после удаления движений документов.
Прежде чем выполнять дальнейшие действия с файлами СУБД, проверим, сколько нераспределенного пространства появилось внутри файла данных. Откроем SQL Server Management Studio (SSMS), щелкнем правой кнопкой мыши по нужной базе данных, перейдем в Reports → Standard Reports → Disk Usage. В отчете отобразится соотношение полезных данных и нераспределенного свободного места (Unallocated Space). Если свободного места внутри файла данных существенно больше 20–30%, операция сжатия имеет практический смысл.
Для того чтобы сгруппировать данные, устранить разреженность и вернуть пустые страницы в общий пул базы данных, необходимо выполнить полное перестроение индексов. Для версий MS SQL Server выполним следующий SQL-скрипт:
USE [ИмяВашейБазы];
GO
-- Для современных версий SQL Server
EXEC sp_MSforeachtable @command1="PRINT '?' ALTER INDEX ALL ON ? REBUILD";
GO
-- Для старых версий (MS SQL Server 2000 / 2005) можно использовать DBCC DBREINDEX:
-- EXEC sp_MSforeachtable @command1="DBCC DBREINDEX ('?')";
-- GO
Перестроение индексов пересоздает структуру хранения таблиц с высокой плотностью заполнения страниц, благодаря чему освободившиеся экстенты становятся доступными для процедуры сжатия.
После перестроения индексов перейдем к уменьшению файла данных. Чтобы переместить занятые страницы из конца файла в его начало и освободить непрерывный блок пространства на диске, требуется операция сжатия с перемещением данных. Рассмотрим варианты ее выполнения.
Через графический интерфейс Management Studio:
Data.Через запрос T-SQL порциями (рекомендуемый способ для больших файлов во избежание зависаний и переполнения журнала транзакций):
USE [ИмяВашейБазы];
GO
-- Узнаем логическое имя файла данных
SELECT name, size/128 AS CurrentSizeMB
FROM sys.database_files
WHERE type_desc = 'ROWS';
GO
-- Выполняем постепенное сжатие файла данных шагами (например, по 1000 МБ)
DBCC SHRINKFILE (N'ЛогическоеИмя_Data', 18000);
GO
DBCC SHRINKFILE (N'ЛогическоеИмя_Data', 16000);
GO
DBCC SHRINKFILE (N'ЛогическоеИмя_Data', 14000);
GO
Если в процессе массового удаления документов или перестроения индексов сильно разросся файл журнала транзакций (.ldf), сжимать его нужно с учетом модели восстановления базы данных (Recovery Model):
USE [ИмяВашейБазы];
GO
DBCC SHRINKFILE (N'ЛогическоеИмя_Log', 0);
GO
USE [ИмяВашейБазы];
GO
-- Создаем резервную копию журнала транзакций
BACKUP LOG [ИмяВашейБазы] TO DISK = N'D:\Backup\LogBackup.trn';
GO
-- Теперь журнал транзакций готов к усечению
DBCC SHRINKFILE (N'ЛогическоеИмя_Log', 0);
GO
При выполнении работ обратим внимание на следующие технические ограничения:
.dat в 1С 7.7: штатный механизм выгрузки данных через Конфигуратор (Администрирование → Выгрузить данные) использует встроенный архиватор с жестким лимитом файла архива в 2 ГБ. Попытка выгрузить базу размером 20 ГБ гарантированно приведет к ошибке переполнения архива либо создаст поврежденный файл, который невозможно загрузить. Поэтому способ сжатия через выгрузку/загрузку данных для баз такого размера неприменим.SHRINKFILE перемещает страницы данных из хвоста файла в свободные блоки в начало, что вызывает сильную физическую фрагментацию индексов. После завершения всех процедур сжатия рекомендуется выполнить легкую дефрагментацию (REORGANIZE) или обновить статистику базы данных командой EXEC sp_updatestats;.