Справочник системных ошибок и решений

Windows Server, Active Directory, 1С:Предприятие, СУБД, Linux, Cisco, MikroTik, Asterisk.

⚠️ Важная информация Все материалы, инструкции, команды и скрипты на сайте предоставлены исключительно в ознакомительных целях. Их применение может повлиять на работу операционной системы, программного обеспечения, баз данных, сетевого оборудования и других компонентов инфраструктуры. Перед выполнением действий создайте резервную копию и по возможности протестируйте изменения в безопасной среде. Пользователь самостоятельно оценивает риски и несет ответственность за результат. При отсутствии необходимых знаний обратитесь к квалифицированному ИТ-специалисту.

PG_PARTITION_MISCONFIG Linux / DevOps

Декларативное секционирование таблиц в PostgreSQL: RANGE, LIST и HASH

Обновлено: 24.08.2026
  • Размер таблицы превышает сотни гигабайт, приводя к деградации построения B-Tree индексов и медленному VACUUM.
  • Удаление старых архивных данных через DELETE WHERE created_at < ... генерирует терабайты WAL и колоссальный Bloat.
  • Планировщик сканирует всю таблицу целиком вместо выборки конкретного временного интервала.

1. Создание секционированной таблицы по диапазону дат (RANGE)

CREATE TABLE measurements (
    id uuid DEFAULT gen_random_uuid(),
    device_id int NOT NULL,
    measured_at timestamptz NOT NULL,
    value numeric(10,2)
) PARTITION BY RANGE (measured_at);

2. Создание секций и дефолтного раздела

-- Секция за Октябрь 2023
CREATE TABLE measurements_y2023m10 PARTITION OF measurements
    FOR VALUES FROM ('2023-10-01 00:00:00+00') TO ('2023-11-01 00:00:00+00');

-- Секция за Ноябрь 2023
CREATE TABLE measurements_y2023m11 PARTITION OF measurements
    FOR VALUES FROM ('2023-11-01 00:00:00+00') TO ('2023-12-01 00:00:00+00');

-- Секция по умолчанию для предотвращения ошибок вставки не попавших значений
CREATE TABLE measurements_default PARTITION OF measurements DEFAULT;

3. Проверка механизма исключения разделов (Partition Pruning)

Убедитесь, что в postgresql.conf включен параметр enable_partition_pruning = on.

EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM measurements 
WHERE measured_at >= '2023-10-15' AND measured_at < '2023-10-20';

В плане выполнения должно присутствовать сканирование только партиции measurements_y2023m10 (0 partitions scanned for other tables).

4. Безопасное отсоединение старых данных без блокировки

ALTER TABLE measurements DETACH PARTITION measurements_y2023m10 CONCURRENTLY;
DROP TABLE measurements_y2023m10;
💡 Практика специалистов: Не создавайте тысячи мелких партиций (например, посуточно на 10 лет вперед). Оптимальное количество активных секций для планировщика PostgreSQL — от нескольких десятков до нескольких сотен.

Частые вопросы (FAQ)

Почему первичный ключ (PRIMARY KEY) в секционированной таблице должен включать ключ партиционирования?

PostgreSQL проверяет уникальность локально внутри каждой партиции. Без включения ключа разбиения в состав PRIMARY KEY ядро не сможет гарантировать уникальность строки по всей таблице.

В чем преимущество DETACH PARTITION CONCURRENTLY?

Оно исключает захват эксклюзивной блокировки AccessExclusiveLock на родительскую таблицу, позволяя выполнять отсоединение устаревших партиций на лету без прерывания пользовательских запросов.

Полезные материалы
Рекомендуем