pg_pathman. Оптим изация секционирования больших и распределенных баз данных
Версия: 1.5.12.
В исходном дистрибутиве установлено по умолчанию: нет.
Связанные компоненты: отсутствуют.
Внимание!
Начиная с Pangolin 5.1.0, использовать
pg_pathman
не рекомендуется. Предлагается перейти на доступное во всех Pangolin декларативное секционирование.По запросу CRPLTFRM-2624 для декларативного секционирования добавлена возможность автоматического, нативного интервального секционирования – подобие
PARTITION BY RANGE
из Oracle Database 11g+.
pg_pathman
исключен из состава продукта.
Секционирование – способ хранения очень большой таблицы, содержащей множество записей. Основной принцип – распределение записей между несколькими малыми физическими таблицами-секциями по значениям поля, набора полей или выражения (ключа секционирования). Под именем таблицы в словарь данных помещается логическое объединение секций – «родительская» или «секционированная» таблица. Данные физически хранятся в таблицах-секциях, а разработчики в логике запросов обраща ются к родительской таблице. Логические запросы к таблице сервер прозрачно разрешает во множество физических операций по секциям таблицы и индексов.
В истории развития PostgreSQL выделяются два подхода к секционированию, которые относятся к двум периодам развития:
- Секционирование с использованием наследования (Partitioning Using Inheritance) – до PostgreSQL 9.6.
- Декларативное секционирование (Native или Declarative Partitioning) – с PostgreSQL 10.
Расширение pg_pathman
- это надстройка над механизмом секционирования с наследованием, которая автоматизирует поддержку секций, добавляет функции для управления данными и дополняет стандартный планировщик оптимизированными путями доступа к секциям по структуре таблицы.
Возможности pg_pathman
:
- секционирование больших баз данных без прерывания их работы;
- ускорение запросов с секционированными таблицами;
- управление существующими секциями и добавление новых;
- добавление в качестве секций сторонних таблиц;
- объединение секционированных таблицы в планах запросов для операций чтения и записи.
Доработка
В СУБД Pangolin для облегчения перехода с pg_pathman
было доработано декларативное секционирование.
Ограничения
Ограничения отсутствуют.
Установка
Необходимо добавить pg_pathman
в настроечный параметр shared_preload_libraries
в конфигурационном файле PostgreSQL.conf
.
Важно:
pg_pathman
может конфликтовать с другими расширениями, которые используют те же функции для перехвата управления. В связи с этим необходимо всегда добавлять это расширение в конец спискаshared_preload_libraries
.
Создайте расширение в БД:
CREATE EXTENSION pg_pathman SCHEMA ext;
Настройка
Настройка не требуется.
Использование модуля
Добавление секционированной таблицы
Расширение поддерживает дв а типа секционирования: по диапазону ключа и по хешу от него. Секционирование по списку значений не поддерживается. Ключом может быть поле, несколько полей (составной ключ) или детерминированное выражение – функция полей. Расширение работает только с теми таблицами, конфигурация которых уже добавлена во внутренние таблицы расширения (pathman_config
, pathman_partition_list
). Для этого требуются констрейнты и триггеры с наименованиями по определенным шаблонам, причем расширение автоматически добавляет и удаляет их. Стандартный способ добавления таблицы – секционировать уже существующую обычную таблицу, заполненную данными или пустую:
-- Секционирование по диапазону, ключ -- поле
create table test (id int8 not null);
select create_range_partitions('test', 'id', 1, 10, 1000);
-- Сек ционирование по хешу, ключ - детерминированное выражение от поля
create table test (data jsonb not null);
select create_hash_partitions('test','(data->>''key'')::int8',100);
Эти функции автоматически создают секции по шаблону, переносят данные (процесс можно отложить и завершить потом – см. ниже), организовывают констрейнты и добавляют таблицу в конфигурацию расширения.
В случае добавления пустой таблицы, заполнить ее данными можно через pg_pathman
– с помощью функциональности добавления секций к таблице (ниже).
Есть способ добавить в расширение уже секционированную таблицу – функция add_to_pathman_config()
, но все внутренние объекты этой таблицы должны соответствовать ожиданиям pg_pathman
. Обычное применение этой функции - восстановить связь с pg_pathman
для таблицы, которая ранее была создана pg_pathman
, исправляя ситуацию после drop extension pg_pathman;
или переноса данных.
Исключение таблицы из конфигурации расширения
Структура и данные в таблице сохранятся. Будет действовать стандартный механизм секционирования наследованием, но не будут автоматически добавляться секции при добавлении записей и применяться оптимизированные планы:
SELECT disable_pathman_for('range_rel');
Завершение отложенного переноса данных
Если секционированная таблица пуста, поскольку она объявлена без переноса данных (флаг partition_data
установлен в значение false
), то можно завершить миграцию данных в фоновом режиме:
-- Запуск фонового переноса данных транзакциями по 1000 записей. В случае блокировки - ожидание 1 с, повторение до 60 попыток.
SELECT partition_table_concurrently('test', 1000, 1.0);
-- Просмотр процессов переноса:
SELECT * FROM pathman_concurrent_part_tasks;
userid | pid | dbid | relid | processed | status
--------+------+-------+-------+-----------+---------
user | 7367 | 16384 | test | 472000 | working
(1 row)
-- Удаление ненужного процесса:
SELECT stop_concurrent_part_task('test');
-- Перенос данных можно перезапускать много раз, повторяя попытки.
-- Когда данные перенесены успешно и полностью, можно исключить бывшую родительскую таблицу из планов, порождаемых pg_pathman:
SELECT set_enable_parent ('test', false);
-- Если ранее при добавлении таблицы partition_data был установлен в true, то полный перенос был выполнен сразу, тогда родительская таблица исключается сразу.
При прерывании процесса текущая транзакция будет отработана полностью, при этом она и все предыдущие транзакции не отменятся.
Объединение секций (range)
Найти названия секций (физических таблиц) и убедиться, что диапазоны подходящие:
select * from pathman_partition_list where parent = 'test'::regclass and range_max::int <= 101;
Соединить секции, слить вместе данные и поправить ограничения:
select merge_range_partitions('test_1', 'test_2');
Расщепление секции на несколько (range)
Найти название секции и убедиться, что диапазон подходит:
select * from pathman_partition_list where parent = 'test'::regclass and range_max::int <= 101;
Расщепить секцию по заданному значению ключа:
select split_range_partition('test_1', 95);
Подключение готовой таблицы в качестве секции (range)
Для того, чтобы подключить готовую таблицу в качестве секции, выполните:
create table test_attach (like abc);
insert into test_attach values (-100), (-50);
select attach_range_partition('abc', 'abc_attach', -100, -10);
select * from pathman_partition_list where parent = 'abc'::regclass
Отсоединение секции в отдельную таблицу (range)
Чтобы выделить секцию как отдельную таблицу, выполните:
select * from pathman_partition_list where parent = 'abc'::regclass and range_min::int <= 0;
select detach_range_partition('abc_attach');