В практике администрирования 1С:Предприятие на СУБД PostgreSQL мы часто сталкиваемся с ситуацией, которая может поставить в тупик даже опытных специалистов. Рассмотрим типичный случай: физический размер базы данных на диске (в SQL) достиг внушительных размеров, например, 129 Гб, однако при создании архивной копии в формате .dt мы получаем файл размером всего 5 Гб. Разберемся, почему возникает такой колоссальный разрыв (более чем в 20 раз) и какие действия необходимо предпринять для устранения проблемы.
Прежде чем приступать к "лечению", давайте проанализируем, что именно хранится в этих двух разных форматах. Это поможет нам понять, где искать "лишние" гигабайты.
Файл выгрузки (.dt) — это специализированный архив 1С. Он содержит:
Важно понимать, что .dt файл — это логическая выжимка. В нем нет индексов базы данных (они строятся заново при загрузке), нет журнала транзакций и, самое главное, в нем нет "мусора" СУБД. Кроме того, данные в нем сжаты.
База данных PostgreSQL на диске хранит:
Именно третий пункт чаще всего является причиной "распухания" базы. Рассмотрим архитектуру PostgreSQL. В этой СУБД используется механизм MVCC (Multi-Version Concurrency Control). Когда 1С удаляет запись или обновляет ее, старая версия строки физически не удаляется с диска, а лишь помечается как "неактуальная" (мертвая). Если механизмы очистки не справляются, эти мертвые записи копятся годами, занимая место, но не попадая в выгрузку .dt.
В рассматриваемом нами случае проблема крылась в интеграции с внешними системами. Давайте посмотрим, как диагностировать подобные ситуации.
Если ваша база "распухла", первым делом проанализируем содержимое регистров сведений. Часто модули интеграции (с Битрикс24, маркетплейсами, сайтами) пишут подробные логи обмена.
В нашем примере "виновником" оказался регистр сведений:
Б24_Логирование
Этот регистр хранил историю всех запросов и ответов интеграции за длительный период. Текстовые логи (XML, JSON) занимают много места, а частое их обновление приводит к быстрой фрагментации таблиц в PostgreSQL.
Для поиска самых больших таблиц в PostgreSQL, если вы не знаете точного имени регистра, можно воспользоваться SQL-запросом к системным таблицам, чтобы выявить лидеров по занимаемому месту. Также полезно сопоставлять имена таблиц SQL (например, _InfoRg12345) с объектами метаданных 1С через функцию ПолучитьСтруктуруХраненияБазыДанных().
После того как мы нашли регистр, который занимает неоправданно много места, нам нужно его очистить. Рассмотрим действия автора темы.
Первый шаг — удаление записей средствами 1С. Это можно сделать:
Однако, здесь нас подстерегает главная особенность PostgreSQL. Допустим, вы удалили миллионы записей из регистра Б24_Логирование. Зайдя в свойства базы данных, вы с удивлением обнаружите, что размер базы на диске не уменьшился ни на байт.
Это происходит потому, что операция DELETE просто помечает пространство как свободное для будущих записей, но не возвращает его операционной системе. Файл таблицы остается того же размера, просто внутри него образуется много "пустот".
Чтобы реально уменьшить размер файлов на диске после удаления данных в 1С, нам необходимо выполнить обслуживание СУБД. Разберем два основных инструмента PostgreSQL.
В теме был задан правильный вопрос:
"autovacuum работает?"
По умолчанию autovacuum включен. Он фоном проходит по таблицам и помечает место для повторного использования. Но он не уменьшает физический размер файла. Он лишь предотвращает его дальнейший рост, разрешая запись новых данных на место удаленных.
Кроме того, при интенсивной записи логов (как в случае с интеграцией Б24) стандартные настройки автовакуума могут быть слишком щадящими, и он просто не будет успевать вычищать мусор.
Это именно то решение, которое помогло автору вернуть размер базы к адекватным значениям.
Команда VACUUM FULL полностью перестраивает содержимое таблицы, переписывая только "живые" данные в новый файл, а старый файл удаляет. Это позволяет вернуть все свободное место операционной системе.
Рассмотрим порядок действий для решения проблемы:
VACUUM FULL требуется монопольный доступ к таблице. Никто не должен работать в базе.Пример команды (выполняется в SQL-консоли):
VACUUM FULL VERBOSE ANALYZE;
Либо можно выполнить сжатие конкретной таблицы, если вы знаете ее имя в SQL:
VACUUM FULL "public"."_InfoRgXXXXX";
-- где _InfoRgXXXXX — имя таблицы регистра сведений
Важное предупреждение: Операция VACUUM FULL требует блокировки таблицы (или всей базы) и может занимать продолжительное время, в зависимости от размера данных и скорости дисков. В случае базы в 129 Гб это может занять от нескольких минут до часов.
Решив проблему единоразово, мы должны позаботиться о том, чтобы база не выросла снова через месяц. Проанализируем, что нужно настроить.
В теме справедливо заметили: "А штатной очистки регистра не предусмотрено? Может забыли настроить регламентное."
Проверьте настройки модуля интеграции (Б24 или любого другого). Там должен быть пункт "Срок хранения логов". Установите разумное значение (например, 7-14 дней). Убедитесь, что регламентное задание 1С, отвечающее за очистку, включено и выполняется без ошибок.
Для высоконагруженных баз 1С параметры PostgreSQL по умолчанию часто не подходят. Рекомендуется настраивать автовакуум более агрессивно, чтобы он срабатывал чаще. Это не уменьшит размер базы, но замедлит её неконтролируемый рост.
Если вам нужно полностью очистить регистр логов (удалить все записи), на уровне SQL эффективнее использовать команду TRUNCATE TABLE. В отличие от DELETE, она мгновенно освобождает место и не создает нагрузку на журнал транзакций. Однако делать это нужно крайне осторожно, понимая соответствие таблиц SQL объектам 1С.
Разница между размером SQL-базы и .dt файлом — это индикатор "здоровья" обслуживания СУБД. Если разрыв становится кратным (как 129 Гб против 5 Гб), следуйте алгоритму:
VACUUM FULL для физического освобождения места на диске.