При административной работе с базами данных 1С Предприятие, развернутыми на базе СУБД MS SQL Server, системные администраторы и разработчики часто сталкиваются с ситуацией, когда незначительное изменение метаданных (например, увеличение длины наименования справочника с 20 до 30 символов) приводит к взрывному росту файла первичных данных (.mdf). В некоторых случаях файл базы данных может мгновенно вырасти в полтора-два раза, вызывая вполне логичный вопрос: нормальное ли это поведение и нужно ли сжимать базу обратно.
В этой статье мы подробно проанализируем, почему происходит скачок размера файла .mdf, что на самом деле происходит внутри структуры данных MS SQL Server в момент реструктуризации, и почему использование встроенного механизма сжатия (Shrink) на продуктивной базе данных может нанести ущерб производительности вашей системы.
Выясним причину, почему изменение длины одного поля заставляет файл данных разрастаться до огромных размеров. Вся причина кроется в механизме реструктуризации таблиц, который использует платформа 1С при взаимодействии с СУБД MS SQL Server.
Когда мы изменяем тип или длину реквизита в конфигураторе 1С и применяем изменения, система не просто выполняет точечную команду изменения колонки (ALTER TABLE). В большинстве случаев платформа 1С выполняет полную пересборку таблицы по следующему алгоритму:
Проанализируем ситуацию с точки зрения дискового пространства. Во время выполнения переборки таблицы в файле .mdf одновременно находились две полные копии таблицы со всеми индексами. Если внутри файла базы данных не было предварительно выделенного свободного пространства, MS SQL Server запустил процедуру автоматического расширения файла (Autogrow) и затребовал у операционной системы дополнительное место на диске.
После того как операция завершилась и старая таблица была удалена, MS SQL Server не возвращает освободившееся место операционной системе. Это пространство помечается внутри файла .mdf как нераспределенное свободное место (Unallocated Space) и удерживается СУБД для будущих операций записи.
Разберем вопрос о том, стоит ли возвращать это место на диске с помощью операции сжатия (Shrink / DBCC SHRINKFILE). На первый взгляд кажется естественным запустить сжатие и освободить место на диске, однако на продуктивных базах данных делать это крайне не рекомендуется без крайней необходимости.
Рассмотрим, к каким последствиям приводит выполнение сжатия файла данных:
ALTER INDEX REBUILD). Но процедура перестроения индексов снова требует выделения значительного количества свободного места! SQL-сервер снова начнет автоматически расширять файл .mdf на диске до предыдущих (или даже больших) размеров.Рассмотрим порядок действий системного администратора в зависимости от текущего состояния сервера:
Если физический диск сервера не переполнен, не делайте ничего. Выделившееся место внутри файла .mdf не потеряно. MS SQL Server будет использовать это предварительно зарезервированное пространство для добавления новых документов, проведения проверок, создания новых записей справочников и регистров. База данных будет работать быстро, так как СУБД не придется постоянно отвлекаться на процедуры физического расширения файла на диске.
Если свободное место на физическом диске исчерпано и это блокирует работу сервера, сжатие выполнить необходимо. Однако делать его нужно строго в два шага:
DBCC SHRINKFILE, указав необходимый целевой размер с небольшим запасом свободного места.REBUILD), которое вызовет повторный рост файла, выполните процедуру **реорганизации индексов** (ALTER INDEX REORGANIZE). Реорганизация упорядочивает страницы индексов без выделения большого объема нового пространства внутри файла .mdf.Чтобы избежать подобных проблем в будущем, проанализируем базовые настройки базы данных в СУБД:
Во-первых, проверьте настройки авторасширения файла (Autogrow). Задавайте приращение размера файла данных в мегабайтах (например, по 512 МБ или 1024 МБ), но ни в коем случае не в процентах. При настройке прироста в процентах на крупных базах данных любое расширение вызывает длительные блокировки и резкие скачки объема файла.
Во-вторых, убедитесь, что в свойствах базы данных параметр AUTO_SHRINK находится в состоянии **False** (отключен). Автоматическое сжатие базы в фоновом режиме является одной из главных причин деградации производительности 1С.