9.1. Функции для распределённой системы #

Postgres Pro Shardman предоставляет ряд функций для распределённой системы. Они позволяют работать с узлами кластера, управлять сегментированными таблицами и распространять выполнение запросов.

Обратите внимание, что данные функции работают только в распределённых системах. Все функции в других разделах данной главы работают в обычных нераспределённых системах.

shardman.broadcast_all_sql(statement text) #

Выполняет оператор в каждой группе репликации.

Предупреждение

Функция shardman.broadcast_all_sql не может выполняться рекурсивно. Попытка это сделать приводит к ошибке «Command execution must be initiated by coordinator» (Выполнение команды должно инициироваться координатором).

shardman.broadcast_query(statement text) #

Действует аналогично shardman.broadcast_all_sql, а также возвращает результаты исполняемого выражения SQL.

Можно задать необязательный параметр include_rgid, тогда в результирующих кортежах будет номер узла, из которого получен кортеж.

Пример с отключённым параметром include_rgid:

SELECT shardman.broadcast_query('SELECT relname FROM pg_class WHERE relkind=''f''');
broadcast_query
-----------------
(t_1_fdw)
(t_2_fdw)
(t_0_fdw)
(t_2_fdw)
(t_0_fdw)
(t_1_fdw)
(6 rows)

Пример с включённым параметром include_rgid:

SELECT shardman.broadcast_query('SELECT relname FROM pg_class WHERE relkind=''f''', include_rgid => true);
broadcast_query
-----------------
(1,t_1_fdw)
(1,t_2_fdw)
(2,t_0_fdw)
(2,t_2_fdw)
(3,t_0_fdw)
(3,t_1_fdw)
(6 rows)
shardman.broadcast_sql(statement text) #

Выполняет оператор в каждой группе репликации, кроме текущей.

Предупреждение

Функция shardman.broadcast_sql не может выполняться рекурсивно. Попытка это сделать приводит к ошибке «Command execution must be initiated by coordinator» (Выполнение команды должно быть инициироваться координатором).

shardman.get_partition_for_value(relid oid, val variadic "any") → shardman.get_partition_for_value_type ( rgid int, local_nspname text, local_relname text, remote_nspname text, remote_relname text) #

Выясняет, к какой секции сегментированной таблицы с oid relid принадлежит val. Возвращает NULL, если сегментированная таблица с oid relid не существует. Возвращает имя локальной схемы и имена отношений. Если значение принадлежит секции, хранящейся в другой группе репликации, также возвращает удалённую схему и имя отношения. Возвращает только rgid, если используется секционирование второго уровня.

Пример:

select * from  shardman.get_partition_for_value('pgbench_branches'::regclass, 20);
 rgid | local_nspname |      local_relname      | remote_nspname |   remote_relname    
------+---------------+-------------------------+----------------+---------------------
    3 | public        | pgbench_branches_17_fdw | public         | pgbench_branches_17
                
shardman.global_analyze() #

Выполняет последовательный анализ сегментированных и глобальных таблиц всего кластера. Сначала эта функция выполняет ANALYZE для всех локальных секций сегментированных таблиц на каждом узле последовательно, а затем отправляет эту статистику на другие узлы. Затем она выбирает один узел для каждой глобальной таблицы и запускает ANALYZE этой таблицы на выбранном узле. Собранная статистика транслируется на все остальные узлы кластера. Обратите внимание, что глобальные таблицы анализируются только один раз, в отличие от сценария запуска ANALYZE на каждом узле.

Пример:

select shardman.global_analyze();

В итоге статистика собирается для всех секций глобальной таблицы, кроме статистики для секционированной таблицы.

shardman.global_analyze_async(force boolean, manage_txn boolean) #

Параллельно производит анализ сегментированных и глобальных таблиц по всему кластеру. В отличие от shardman.global_analyze такая процедура выполняется командой ANALYZE на всех локальных секциях сегментированных таблиц одновременно на всех узлах. Кроме того, при этом секции не блокируются до конца операции.

Параметр force задаёт частоту выполнения команды ANALYZE этой процедурой. При значении true (по умолчанию) команда ANALYZE выполняется всегда. При значении false во избежание частых вызовов команды ANALYZE используются autovacuum_analyze_threshold и autovacuum_analyze_scale_factor.

Параметр manage_txn определяет способ обработки операций COMMIT по завершении команды ANALYZE. При значении true (по умолчанию) COMMIT выполняется по завершении команды ANALYZE для каждой сегментированной или глобальной таблицы. При значении false COMMIT не выполняется.

Пример:

CALL shardman.global_analyze_async(force="false",manage_txn="true");
shardman.attach_subpart(relid regclass, snum int, partition_bound text[]) #

Присоединяет ранее отсоединённую подсекцию с номером snum к локально секционированной таблице relid в качестве секции для указанных значений в диапазоне partition_bound. Все таблицы подсекции и сторонние таблицы уже должны существовать. Параметр partition_bound — это пара нижней и верхней границ секции. Если и нижняя, и верхняя границы равны NULL, подсекция присоединятся как стандартная.

Операция выполняется на уровне кластера.

Пример:

select shardman.attach_subpart('pgbench_history'::regclass, 1,$${'2021-01-01 00:00', '2022-01-01 00:00'}$$);
shardman.create_subpart(relid regclass, snum int, partition_bound text[]) #

Создаёт подсекцию с номером snum для локально секционированной таблицы relid в качестве секции для значений в диапазоне partition_bound. Параметр partition_bound — это пара нижней и верхней границ секции. Если и нижняя, и верхняя границы равны NULL, подсекция создаётся как стандартная. Если номер подсекции не указан, он будет выбран в качестве следующего доступного номера секции.

Операция выполняется на уровне кластера.

Примеры:

select shardman.create_subpart('pgbench_history'::regclass, 1, $${'2021-01-01 00:00', '2022-01-01 00:00'}$$);
select shardman.create_subpart('pgbench_history'::regclass, partition_bound:=$${'2022-01-01 00:00', '2023-01-01 00:00'}$$);
shardman.detach_subpart(relid regclass, snum int) #

Отсоединяет подсекцию с номером snum от локально секционированной таблицы relid. Номер секции можно определить из представления shardman.subparts.

Операция выполняется на уровне кластера.

Пример:

select shardman.detach_subpart('pgbench_history'::regclass, 1);
shardman.drop_subpart(relid regclass, snum int) #

Удаляет подсекцию с номером snum из локально секционированной таблицы relid. Номер секции можно определить из представления shardman.subparts.

Операция выполняется на уровне кластера.

Пример:

select shardman.drop_subpart('pgbench_history'::regclass, 1);
shardman.am_coordinator() #

Проверяет, является ли текущий сеанс координатором запроса. Данная проверка позволят избежать случаев повторного срабатывание триггеров глобальных и сегментированных таблиц, когда триггер срабатывает сначала в координаторе запроса, а потом на удалённых узлах при изменении данных.

SELECT shardman.am_coordinator();
am_coordinator
----------------
t
(1 row)

Пример проверки триггерной функцией координатора запросов:

CREATE OR REPLACE FUNCTION trg_func() RETURNS TRIGGER
AS $$
BEGIN
IF NOT shardman.am_coordinator() THEN
        -- exit on non coordinator
        RETURN NEW;
END IF;
-- execute only by coordinator
RAISE WARNING 'Trigger fired!';
END
$$ LANGUAGE plpgsql;