Как бороться с раздуванием (bloat) системных каталогов PostgreSQL при работе с 1С:Предприятие?

Системный администратор 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа связки 1С:Предприятие и PostgreSQL имеет свои уникальные особенности, связанные с тем, как платформа взаимодействует с базой данных. Одной из наиболее острых проблем является так называемое «раздувание» (bloat) системных каталогов СУБД. Проявляется это в том, что база данных начинает занимать значительно больше места на диске, чем реально содержащиеся в ней данные, а стандартные процедуры обслуживания перестают помогать. Особенно сильно страдает таблица pg_attribute, в которой хранятся данные о колонках всех таблиц. В этой статье мы подробно разберем, почему это происходит и как правильно обслуживать такие базы.

Почему раздуваются системные каталоги?

Разберем первопричину ситуации. Архитектура 1С подразумевает чрезвычайно активное использование временных таблиц. При выполнении практически любого запроса, подбора в формах или формировании отчета платформа создает, использует и тут же удаляет сотни и тысячи временных таблиц. Каждая такая таблица должна быть зарегистрирована в системных каталогах PostgreSQL. Записи о ней попадают в pg_class, данные о её полях — в pg_attribute, индексы — в pg_index, а типы данных — в pg_type.

Когда временная таблица удаляется, соответствующие строки в системных каталогах помечаются как удаленные (dead tuples). Проблема в том, что обычный VACUUM только помечает это место как свободное для повторного использования самой СУБД, но не возвращает его операционной системе. Если интенсивность создания таблиц высока, системный каталог растет быстрее, чем очистка успевает срабатывать, что приводит к гигантским размерам файлов pg_attribute (десятки гигабайт), хотя полезных данных там может быть всего на несколько сотен мегабайт.

Анализ проблемы и использование VACUUM FULL

Проанализируем ситуацию, когда стандартный VACUUM не справляется. Если вы обнаружили, что место на диске тает, а топ-1 по размеру в базе занимает pg_catalog.pg_attribute, единственным встроенным способом радикально сжать таблицу является команда:


VACUUM FULL pg_catalog.pg_attribute;
ANALYZE pg_catalog.pg_attribute;

Важный нюанс: команда VACUUM FULL пересоздает таблицу «с нуля», полностью удаляя пустое пространство. Однако она накладывает Access Exclusive Lock. Это означает, что пока процедура не завершится, ни один пользователь не сможет начать работу с базой, так как доступ к системному каталогу будет заблокирован. Для баз 1С, работающих в режиме 24/7, это может стать критическим фактором. Кроме того, такая операция создает огромную нагрузку на дисковую подсистему и сеть при наличии репликации.

Настройка Autovacuum под специфику 1С

Вместо того чтобы полностью отключать автовакуум и запускать его вручную раз в сутки, рассмотрим более эффективный метод — индивидуальную настройку параметров для системных таблиц. Мы можем заставить PostgreSQL очищать pg_attribute гораздо агрессивнее, чем остальные таблицы базы данных. Выясним, как это сделать программно через SQL-запрос:


ALTER TABLE pg_catalog.pg_attribute SET (
  autovacuum_vacuum_scale_factor = 0.01,
  autovacuum_vacuum_threshold = 100,
  autovacuum_analyze_scale_factor = 0.005
);

В данном примере мы установили очень низкий порог срабатывания (scale factor). Теперь автовакуум будет приходить в эту таблицу гораздо чаще, не дожидаясь, пока в ней накопится 20% мусора. Это позволяет поддерживать таблицу в «подтянутом» состоянии и предотвращает лавинообразный рост bloat.

Влияние длительных транзакций

Разберем ситуацию, когда даже настроенный автовакуум не помогает. Основная причина здесь — наличие в базе «зависших» транзакций. Если в 1С открыта транзакция (например, из-за ошибки в коде или очень долгого отчета), PostgreSQL не имеет права удалять старые версии строк, которые были созданы после начала этой самой старой активной транзакции. Пока транзакция висит, VACUUM бессилен.

Рекомендуется регулярно мониторить состояние процессов. Посмотрим на запрос, позволяющий выявить долгоживущие транзакции:


SELECT pid, now() - xact_start AS duration, query, state
FROM pg_stat_activity
WHERE state != 'idle' AND (now() - xact_start) > interval '1 hour';

Если вы видите транзакции, которые длятся часами, — это прямой путь к раздуванию системных каталогов. Такие сессии в 1С нужно завершать через консоль кластера или программно.

Оптимизация параметров temp_buffers и дисковой подсистемы

Поскольку 1С создает массу временных объектов, проанализируем настройку буферов. Параметр temp_buffers определяет объем оперативной памяти, выделяемой для временных таблиц в рамках каждой сессии. Если временная таблица не помещается в этот лимит, она сбрасывается на диск в pg_temp.

Для систем с 1С рекомендуется увеличивать этот параметр в postgresql.conf:


# Пример настройки для высоконагруженных систем
temp_buffers = 128MB 

Это не только ускорит работу самих запросов 1С, но и снизит косвенную нагрузку на регистрацию дисковых объектов в системных каталогах.

Использование внешних инструментов: pg_repack и pg_compact

Если блокировки от VACUUM FULL недопустимы, рассмотрим альтернативные инструменты, такие как pg_repack. Это расширение позволяет пересобрать таблицу и её индексы в фоновом режиме без эксклюзивной блокировки. Принцип работы заключается в создании временной таблицы, куда переносятся живые данные, и последующей быстрой подмене оригинальной таблицы.

Также стоит обратить внимание на скрипты типа pg_compact. Они работают более тонко: перемещают последние записи в пустые места в начале таблицы, чтобы в итоге освободить место в конце файла. После этого обычный VACUUM может легко «отрезать» (truncate) пустой хвост файла и вернуть место операционной системе без блокировки всей базы.

Обслуживание индексов системных каталогов

Часто основное место занимает не сама таблица pg_attribute, а её индексы. Рассмотрим эффективный способ борьбы с раздуванием индексов в современных версиях PostgreSQL (12 и выше). Вместо блокирующего REINDEX, мы можем использовать команду с параметром CONCURRENTLY:

REINDEX TABLE CONCURRENTLY pg_catalog.pg_attribute;

Эта процедура перестроит индексы в фоновом режиме, позволяя пользователям 1С продолжать работу. Это значительно снижает деградацию производительности, возникающую из-за огромных и фрагментированных индексных деревьев в системных таблицах.

Резюме и рекомендации

Подведем итоги нашего анализа. Для стабильной работы 1С на PostgreSQL необходимо:

  1. Не отключать автовакуум, а настраивать его агрессивность индивидуально для pg_attribute, pg_class и других таблиц pg_catalog.
  2. Следить за «брошенными» сеансами в 1С и незавершенными транзакциями в СУБД.
  3. Если база уже сильно раздута, провести разовое обслуживание через VACUUM FULL в технологическое окно или использовать pg_repack.
  4. Увеличить temp_buffers для снижения нагрузки на дисковую подсистему при работе с временными таблицами.
  5. Периодически выполнять REINDEX CONCURRENTLY для системных каталогов.

Соблюдение этих правил позволит избежать внезапного исчезновения свободного места на диске и обеспечит высокую скорость работы платформы 1С:Предприятие.

← На главную