Типичная ситуация при администрировании клиент-серверных баз 1С: информационная база стабильно росла на 1 Гб в месяц, но после очередного обновления конфигурации файл базы данных (.mdf) внезапно увеличился на 10–15 Гб или более. При этом фактический объем первичных документов практически не изменился.
В этой статье мы подробно разберем внутренние механизмы платформы 1С:Предприятие и СУБД MS SQL, выясним причину аномального роста таблиц и рассмотрим пошаговый план по диагностике, исправлению учетных ошибок и физическому сжатию базы данных.
В платформе 1С для регистров накопления остатков создаются две основные физические таблицы на уровне СУБД:
_AccumRgT) — хранит рассчитанные остатки. В ней находятся актуальные итоги (на системную дату 01.11.3999), а также промежуточные срезы на начало каждого месяца вплоть до даты рассчитанных итогов.Проанализируем механику работы итогов: если по уникальной комбинации измерений (например, конкретная номенклатура, склад, характеристика, серия и документ партии) остаток закрывается в ноль, в таблице движений присутствуют две записи (плюс и минус), а в таблице итогов запись обнуляется и не переносится на будущие месяцы.
Если же регистр не закрывается (например, приход лег на одну аналитику или партию, а расход списался с другой или с пустым значением), то незакрытый остаток считается активным. Платформа 1С физически дублирует эту строку в таблице итогов за каждый последующий месяц.
Если в базе партионный учет не закрывался на протяжении нескольких лет, то при очередном обновлении конфигурации или реструктуризации платформа сдвигает границу рассчитанных итогов вперед к текущей дате. В этот момент происходит лавинообразное размножение незакрытых строк: сотни тысяч зависших хвостов умножаются на количество месяцев сдвига, единовременно генерируя миллионы записей в таблице _AccumRgT, что приводит к взрывному росту файла .mdf.
Прежде чем выполнять любые действия, необходимо точно определить, какие именно таблицы занимают основной объем. Для этого выполним анализ физического распределения дискового пространства в MS SQL Management Studio или с помощью специализированных отчетов 1С.
Выясним причину с помощью системного отчета в MS SQL Server Management Studio (SSMS):
В отчете смотрим на соотношение объема таблицы движений (_AccumRg) и таблицы итогов (_AccumRgT). Если таблица итогов по регистру партий (или остатков товаров) в разы превышает размер таблицы самих записей, это однозначно указывает на наличие незакрытых остатков за длительный период.
Также проверяем наличие временных служебных таблиц. При сбоях или отмене реструктуризации во время обновления в базе могут остаться брошенные таблицы с префиксами _1Cv8_tmp_ или суффиксами _NG, занимающие гигабайты пространства.
Пересчет итогов без исправления данных не уменьшит размер таблицы итогов, так как платформа просто заново пересчитает и запишет те же самые незакрытые остатки. Рассмотрим, почему партии и регистры могут не закрываться:
Разберем способы устранения проблемы:
Вариант А. Корректировка зависших остатков (рекомендуемый без перепроведения прошлых лет)
Если база ведется много лет и перепроведение документов за прошлые периоды недопустимо, оптимальным решением является точечное закрытие зависших хвостов с помощью документа КорректировкаЗаписейРегистров:
Вариант Б. Свертка информационной базы
Если в базе накоплено многолетнее количество ошибок, эффективным решением является свертка базы на определенную дату (например, на начало предыдущего или текущего года). Свертка формирует входящие остатки и удаляет старые движения, что избавляет базу от необходимости хранить срезы итогов за прошлые годы.
Если партионный учет в разрезе прошлых периодов не используется или был заменен другим механизмом, мы можем ограничить расчет итогов:
Сдвиг границы расчета итогов назад позволяет платформе не формировать ежемесячные срезы за ненужные периоды. Для этого используется метод:
РегистрыНакопления.ПартииТоваровНаСкладах.УстановитьПериодРассчитанныхИтогов(ДатаНачалаПериода);
Если регистр полностью устарел и расчет остатков по нему больше не требуется, можно отключить использование итогов:
РегистрыНакопления.УстаревшийРегистр.УстановитьИспользованиеИтогов(Ложь);
После того как данные в регистрах выровнены и лишние итоги удалены, физический размер файла .mdf на диске автоматически не уменьшится — MS SQL оставляет освобожденное место внутри файла под будущие операции. Для возврата места на диск выполним комплекс процедур обслуживания.
Разберем по шагам правильный порядок действий:
TRUNCATEONLY освобождает только свободное место в конце файла:
USE [ИмяБазыДанных]
GO
DBCC SHRINKFILE (N'ИмяФайлаДанных', 0, TRUNCATEONLY);
GO
USE [ИмяБазыДанных]
GO
DBCC SHRINKFILE (N'ИмяФайлаДанных', ЖелаемыйРазмерВМБ);
GO
USE [ИмяБазыДанных]
GO
EXEC sp_MSforeachtable @command1="ALTER INDEX ALL ON ? REBUILD";
GO
USE [ИмяБазыДанных]
GO
EXEC sp_updatestats;
GO
Альтернативный способ очистки через выгрузку в .dt:
Самый простой и чистый способ физически сжать базу после исправления движений — выгрузить информационную базу в файл выгрузки (.dt) из конфигуратора, создать на MS SQL чистую пустую базу данных и загрузить .dt обратно. При этом все таблицы, индексы и страницы данных создаются заново с нулевой фрагментацией и минимальным физическим размером.