Перейти к основному содержимому

Устранение перестроения индекса при увеличении размерности типа колонки в партиционированных таблицах

Описание

В СУБД Pangolin реализовано поведение, что при изменении размерности колонки партиционированной таблицы не происходит перестроение локального индекса, построенного по этой колонке.

В основе данного решения использована логика сохранения RelFileNode, которая реализована и используется для обычных таблиц в оригинальном PostgreSQL. Эта логика была воспроизведена для всех партиций таблицы, к которой применяется команда ALTER TABLE.

Описание решения

На этапе обработки операции ALTER TABLE формируется список RelFileNode входящих индексов с сохранением их имен и OID namespace. В данный список включаются только совместимые индексы. Проверка совместимости выполняется с использованием оригинальной функции, применяемой для непартиционированных таблиц.

Сформированный список используется на этапе создания субиндексов. Сопоставление выполняется по имени субиндекса и OID namespace таким образом, чтобы при пересоздании индекс фактически создавался пустым, без данных. На финальном этапе обработки для каждого сохраненного RelFileNode выполняется подстановка соответствующих объектов файловой системы в уже существующий пустой индекс.

В результате индексы и их субиндексы логически пересоздаются и получают новые OID, однако используемые RelFileNode сохраняют свои значения без изменений. Такой подход позволяет существенно сократить время выполнения операции ALTER TABLE для совместимых изменений.

Решение о применимости оптимизации принимается по следующим критериям, учитывается:

  • бинарная совместимость типов;
  • размер целевой колонки (>=);
  • возможность изменения специфических параметров колонки (например, collation, timezone и других).

Назначение

Значительно ускорить перестроение индексов при выполнении операции ALTER TABLE для партиционированных таблиц аналогично механизму для ускорения этой операции для непартиционированных таблиц в ядре PostgreSQL.

Ограничения

Ограничения полностью соответствуют ограничениям оригинальной версии на перестроение индексов для непартиционированных таблиц и включают:

  • бинарную совместимость старого и нового типа колонки;
  • равный или больший размер нового типа колонки;
  • специфичные для типа ограничения (например, timezone для колонки даты);
  • отсутствие применимости для глобальных индексов (ГИ).

Настройка

Функциональность не требует отдельно настройки и доступна сразу после установки СУБД.

Сведения

Отключение данной функциональность невозможно.

Сценарии использования

Уменьшение размера колонки

Предусловия

  1. Создайте партиционированную таблицу:

    CREATE TABLE test_expl_glob (
    id bigserial,
    start_date timestamp,
    status1 varchar(1),
    status2 varchar(1)
    )
    PARTITION BY RANGE (start_date);
  2. Создайте индексы:

    CREATE index test_expl_glob_idx_1 ON test_expl_glob USING btree (status1);
    CREATE index test_expl_glob_idx_2 ON test_expl_glob USING btree (status2);
  3. Создайте партиции:

    CREATE TABLE test_expl_glob1 PARTITION OF test_expl_glob FOR VALUES FROM ('2024-07-02 00:00:00') TO ('2024-07-03 00:00:00');
    CREATE TABLE test_expl_glob2 PARTITION OF test_expl_glob FOR VALUES FROM ('2024-07-03 00:00:00') TO ('2024-07-04 00:00:00');
    CREATE TABLE test_expl_glob3 PARTITION OF test_expl_glob FOR VALUES FROM ('2024-07-04 00:00:00') TO ('2024-07-05 00:00:00');
  4. Заполните таблицу данными:

    INSERT INTO test_expl_glob SELECT g.id,'2024-07-02 15:34:40.472880','A','C' FROM generate_series(1,3000000) g(id);
    INSERT INTO test_expl_glob SELECT g.id,'2024-07-03 15:34:40.472880','A','C' FROM generate_series(1,3000000) g(id);
    INSERT INTO test_expl_glob SELECT g.id,'2024-07-04 15:34:40.472880','A','C' FROM generate_series(1,3000000) g(id);

Шаги

  1. Выполните команду ALTER TABLE без перестроения индекса:

    ALTER TABLE test_expl_glob ALTER COLUMN status1 TYPE varchar(2);
    ALTER TABLE test_expl_glob ALTER COLUMN status1 TYPE varchar(200);
    ALTER TABLE test_expl_glob ALTER COLUMN status1 TYPE varchar(500);
  2. Выполните команду ALTER TABLE с перестроением индекса (уменьшение ширины колонки):

    ALTER TABLE test_expl_glob ALTER COLUMN status1 TYPE varchar(1);

    При изменении размерности колонки status1 партиционированной таблицы test_expl_glob не происходит перестроение локального индекса, построенного по этой колонке.