При администрировании крупных баз данных 1С специалисты часто сталкиваются со следующей проблемой: после проведения свертки информационной базы или массового удаления старых документов (например, когда из базы удалили 70-80% документов, оставив лишь небольшую часть данных) физический размер файла базы данных практически не изменяется. Например, база весила 20 ГБ, а после удаления огромного массива документов стала весить 15 ГБ, хотя должна была уменьшиться в разы.
В этой статье мы подробно разберем по шагам, почему так происходит, выясним причину этого технического поведения СУБД, а также рассмотрим все доступные методы анализа размера таблиц как встроенными средствами 1С, так и инструментами сторонних СУБД (MS SQL Server, PostgreSQL) и специальными утилитами для файловых баз.
Когда вы запускаете обработку удаления объектов в 1С (например, удаляете документы и записи регистров), платформа отправляет СУБД команды на удаление строк из соответствующих физических таблиц. Однако СУБД (будь то Microsoft SQL Server, PostgreSQL или файловый движок 1С) физически удаляет только записи внутри страниц данных, но не возвращает освободившееся место на диске операционной системе.
Это связано со спецификой работы систем управления базами данных:
.mdf в MS SQL или .1CD в файловом варианте) сохраняет свой прежний размер на диске. Это сделано для повышения производительности: операция расширения файла на диске ресурсоемкая, поэтому СУБД удерживает выделенное пространство «про запас».Рассмотрим подробнее, как проанализировать структуру хранения базы данных, найти самые тяжелые таблицы (которые чаще всего оказываются регистрами сведений или накопления) и физически уменьшить файлы базы на диске. Для комплексной оценки распределения пространства подойдёт инструмент для построения карты объёмов базы данных.
Начиная с версии платформы 8.3.15, разработчикам стали доступны встроенные программные методы, позволяющие оценить структуру и размер таблиц без прямого доступа к СУБД. Это крайне удобно, так как код работает на любой СУБД и даже в файловом варианте. Для автоматического расчёта можно использовать отчёт для анализа размера таблиц базы данных по метаданным.
Для решения нашей задачи мы можем использовать комбинацию двух методов:
ПолучитьСтруктуруХраненияБазыДанных() — позволяет сопоставить понятные объекты метаданных 1С (например, РегистрНакопления.Продажи) с именами физических таблиц в базе данных (например, _AccumRg12345).ПолучитьРазмерДанныхБазыДанных() — возвращает точный размер данных, занимаемых конкретным объектом метаданных.Проанализируем пример кода, который выводит список всех объектов метаданных и их физический размер:
ВыборкаОбъектов = Новый Массив;
ВыборкаОбъектов.Добавить("Справочник.Номенклатура");
ВыборкаОбъектов.Добавить("РегистрНакопления.Продажи");
ТаблицаРазмеров = ПолучитьРазмерДанныхБазыДанных(ВыборкаОбъектов);
Для Каждого СтрокаРазмера Из ТаблицаРазмеров Цикл
Сообщить("Объект: " + СтрокаРазмера.ИмяМетаданных + " -> Размер: " + СтрокаРазмера.Размер + " байт");
КонецЦикла;
Важное предупреждение: Метод ПолучитьРазмерДанныхБазыДанных() рассчитывает объем чистых данных на основе функции DATALENGTH на уровне СУБД. Он не учитывает размер индексов, историю данных и служебные таблицы платформы. Кроме того, на больших базах данных выполнение этого метода может занять длительное время и создать серьезную нагрузку на дисковую подсистему СУБД, так как происходит последовательное сканирование таблиц. Для поиска самых объёмных объектов подойдёт обработка обследования базы. Она показывает размеры и физические таблицы; для учёта индексов потребуется отдельно выполнить предложенный SQL-запрос и загрузить результат.
Если ваша база данных работает под управлением MS SQL Server, у вас есть мощные штатные средства анализа дискового пространства.
Использование стандартного отчета в SSMS (SQL Server Management Studio):
Перед вами откроется наглядная интерактивная таблица, в которой будут представлены следующие колонки:
_InfoRg12345). Чтобы понять, какому объекту 1С соответствует это имя, используйте метод ПолучитьСтруктуруХраненияБазыДанных() или специализированные обработки.Использование системных SQL-запросов:
Для быстрого получения точной информации о размерах таблиц без графического интерфейса можно запустить следующий SQL-запрос к системным представлениям:
SELECT
t.NAME AS TableName,
p.rows AS RowCounts,
SUM(a.total_pages) * 8 AS TotalSpaceKB,
SUM(a.used_pages) * 8 AS UsedSpaceKB,
(SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB
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
WHERE
t.is_ms_shipped = 0
AND i.object_id > 255
GROUP BY
t.Name, p.Rows
ORDER BY
TotalSpaceKB DESC;
Для баз данных, работающих на PostgreSQL, самым простым и надежным способом определения размера таблиц является выполнение SQL-запроса через утилиту pgAdmin или консоль psql.
В PostgreSQL для получения полной картины (включая индексы и системные TOAST-таблицы, в которых 1С хранит файлы и длинные строки типа неограниченной длины) используется функция pg_total_relation_size(). Для приведения результатов к человекочитаемому виду используется функция pg_size_pretty().
Выполним следующий запрос, чтобы получить топ-20 самых тяжелых таблиц в базе:
SELECT
relname AS table_name,
pg_size_pretty(pg_total_relation_size(PG_CLASS.oid)) AS total_size,
pg_size_pretty(pg_relation_size(PG_CLASS.oid)) AS data_size,
pg_size_pretty(pg_total_relation_size(PG_CLASS.oid) - pg_relation_size(PG_CLASS.oid)) AS external_size
FROM
pg_class PG_CLASS
LEFT JOIN
pg_namespace PG_NAMESPACE ON PG_NAMESPACE.oid = PG_CLASS.relnamespace
WHERE
nspname NOT IN ('pg_catalog', 'information_schema')
AND relkind = 'r'
ORDER BY
pg_total_relation_size(PG_CLASS.oid) DESC
LIMIT 20;
Если ваша база данных файловая, вы не сможете использовать стандартные инструменты СУБД. Однако для файловых баз существуют проверенные временем решения:
.1CD. С её помощью можно открыть копию базы данных, перейти на вкладку таблиц и отсортировать их по физическому размеру на диске. Утилита показывает размер полей неограниченной длины (BLOB), что очень важно для поиска тяжелых хранилищ значений (например, присоединенных файлов)..1CD и строят интерактивный отчет прямо в режиме «1С:Предприятие».Техническая деталь: Помните, что в классическом формате файловой базы размер одной таблицы ограничен 4 ГБ. Начиная с версии платформы 8.3.8, при создании базы можно задавать размер страницы 8 КБ, 16 КБ, 32 КБ или 64 КБ (вместо стандартных 4 КБ). Это позволяет обойти лимит в 4 ГБ, однако сама база из-за этого может весить на 20-30% больше на диске из-за специфики внутреннего распределения страниц.
Чтобы не писать запросы вручную, рекомендуется использовать готовые решения от сообщества разработчиков 1С:
После того как вы нашли «тяжелые» таблицы, почистили ненужные регистры и удалили старые документы, вам необходимо вернуть свободное место операционной системе.
Рассмотрим по шагам действия для различных вариантов размещения базы:
Для файловой базы:
.1CD, удалив все пустые страницы..dt), создайте новую пустую файловую базу и загрузите этот .dt файл обратно. При выгрузке в .dt переносятся только актуальные полезные данные, поэтому при обратной загрузке файл .1CD создается заново в минимально возможном объеме.Для MS SQL Server:
DBCC SHRINKDATABASE (Имя_Вашей_Базы);
ALTER INDEX ALL REBUILD;
Для PostgreSQL:
VACUUM FULL;
Обратите внимание: Эта команда требует монопольного доступа к базе данных и полностью блокирует таблицы на время своей работы.pg_repack, которая позволяет пересобирать таблицы и освобождать место на диске «на лету» без жестких блокировок транзакций 1С.Мы подробно разобрали, как устроен механизм выделения памяти в базах данных 1С, изучили программные методы платформы, системные запросы к СУБД и способы сжатия физических файлов. Теперь вы сможете оперативно находить переполненные регистры и эффективно администрировать дисковое пространство ваших серверов.