22.2. Подключение и работа с кластером Postgres Pro Shardman #
Кластер состоит из четырёх сегментов. Cекции данных основной сегментированной таблицы распределяются по остальным сегментам таким образом:
Для ключа сегментирования ticket_no
:
tickets_0
— сегмент-1 (узел кластераnode1
)tickets_1
— сегмент-2 (узел кластераnode2
)tickets_2
— сегмент-3 (узел кластераnode3
)tickets_3
— сегмент-4 (узел кластераnode4
)
Для ключа сегментирования book_ref
:
bookings_0
— сегмент-1 (узел кластераnode1
)bookings_1
— сегмент-2 (узел кластераnode2
)bookings_2
— сегмент-3 (узел кластераnode3
)bookings_3
— сегмент-4 (узел кластераnode4
)
Ниже приведены примеры для ключа сегментирования book_ref
, но указанный в подразделах код будет справедлив и для ключа сегментирования ticket_no
.
Не стоит рассматривать данный код как оптимальный или пригодный для производственной среды. Он дан только как пример реализации создания пула соединений для работы с кластером Postgres Pro Shardman.
Общее для всех приведённых примеров — строка подключения к кластеру, которая должна содержать имена узлов, номера TCP-портов, имя и пароль пользователя, имя базы данных для подключения и набор параметров сеанса.
Такую строку можно получить с помощью утилиты shardmanctl. В простейшем случае строка будет выглядеть так:
$ shardmanctl getconnstr dbname=postgres host=node1,node2,node3,node4 port=5432,5432,5432,5432
Её можно использовать для подключения к узлам кластера или для создания пула соединений в приложениях.
22.2.1. SQL #
В Postgres Pro Shardman реализовано несколько удобных функций и представлений для наблюдения за кластером:
Вывод списка глобальных таблиц
Вывод списка сегментированная таблиц
Вывод списка глобальных последовательностей
Вычисление номера сегмента по ключу сегментирования
Выполнение
ANALYZE
для всех глобальных и сегментированных таблиц в кластере
22.2.1.1. Отображение списка глобальных таблиц #
Для вывода всех глобальных таблиц в кластере используйте представление shardman.global_tables
:
postgres=# select relname as table_name, nspname as schema from shardman.global_tables; table_name | schema ------------+---------- aircrafts | bookings seats | bookings airports | bookings flights | bookings (4 rows)
22.2.1.2. Отображение списка сегментированная таблиц #
Для получения сведений обо всех сегментированных таблицах в кластере выполните запрос к представлению shardman.sharded_tables
как показано ниже:
postgres=# select relname as table_name, nparts as partitions, colocated_with::oid::regclass::text as colocated_with, nspname as schema from shardman.sharded_tables; table_name | partitions | colocated_with | schema -----------------+------------+----------------+---------- bookings | 4 | | bookings ticket_flights | 4 | bookings | bookings tickets | 4 | bookings | bookings boarding_passes | 4 | bookings | bookings (4 rows)
22.2.1.3. Отображение списка глобальных последовательностей #
Для вывода всех глобальных последовательностей в кластере используйте представление shardman.sequence
:
postgres=# select seqns as schema, seqname as sequence_name, seqmin as min_value, seqmax as max_value, seqblk as bulk_size from shardman.sequence; schema | sequence_name | min_value | max_value | bulk_size ----------+-------------------------+-----------+---------------------+----------- bookings | flights_flight_id_seq | 262145 | 9223372036854775807 | 65536 (1 rows)
22.2.1.4. Вычисление номера сегмента по ключу сегментирования #
Для вывода имени секции, содержащей данные и имя группы репликации вызовите функцию shardman.get_partition_for_value()
. Например, пусть book_ref
= 0369E5:
postgres=# select * from shardman.get_partition_for_value( 'bookings'::regclass, '0369E5'::character(6)); rgid | local_nspname | local_relname | remote_nspname | remote_relname ------+---------------+---------------+----------------+---------------- 1 | bookings | bookings_0 | bookings | bookings_0
Этот вывод показывает, что данные в секции bookings_0
таблицы bookings
расположены в том же узле, в котором выполнялся запрос.
Выполните запрос, показывающий имя сервера, где находится секция с данными. Если подключиться к серверу, содержащему искомую секцию, то в выводе имени сервера будет написано «current server» (текущий сервер). Если данные расположены в другом сегменте, показывается имя узла мастера сегмента:
SELECT p.rgid, local_relname AS partition_name, CASE WHEN r.srvid IS NULL THEN 'current server' ELSE (SELECT (SELECT split_part(kv, '=', 2) FROM (SELECT unnest(fs.srvoptions) as kv) x WHERE split_part(kv, '=', 1) = 'host') FROM shardman.repgroups rg JOIN pg_catalog.pg_foreign_server AS fs ON fs.oid = rg.srvid WHERE rg.id = p.rgid) END AS server_name FROM shardman.get_partition_for_value('bookings'::regclass, '0369E5'::character(6)) p JOIN shardman.repgroups AS r ON r.id = p.rgid; rgid | partition_name | server_name ------+----------------+---------------- 1 | bookings_0 | current server (1 row)
При выполнении запроса с другим ключом сегментирования — 0369E6 — результат будет таким:
rgid | partition_name | server_name ------+----------------+------------- 4 | bookings_3_fdw | node4 (1 row)
Видно, что секция находится на узле node4
.
Также обратите внимание, что параметр shardman.rgid
позволяет вам найти номер узла с сеансом подключения. Для этого выполните следующий запрос:
SELECT pg_catalog.current_setting('shardman.rgid');
Это значение можно использовать для определения расположения секций в подобных запросах.
Функция shardman.get_partition_for_value()
в основном предназначена для административных целей и лучшего понимания топологии данных.
Как правило, административные функции не следует использовать при написании SQL-кода для доступа к данным.
22.2.1.5. Расположение секций сегментированных таблиц по сегментам #
Список всех сегментированных таблиц в схеме bookings
, количество их секций и распределение по серверам (сегментам) можно получить из метаданных Postgres Pro Shardman на любом узле кластера.
Рассмотрим следующий запрос:
SELECT p.rel::regclass::text AS table_name, p.pnum, p.rgid, r.srvid, fs.srvname FROM shardman.parts p JOIN shardman.repgroups r ON p.rgid = r.id LEFT OUTER JOIN pg_foreign_server fs ON r.srvid = fs.oid;
Чтобы выяснить как распределены данные, объедините этот запрос с подзапросом из Раздел 22.2.1.4:
SELECT p.rel::regclass AS table_name, st.nparts AS total_parts, p.pnum AS num_part, CASE WHEN r.srvid IS NULL THEN 'connected server' ELSE (SELECT split_part(kv, '=', 2) FROM (SELECT unnest(fs.srvoptions) AS kv) x WHERE split_part(kv, '=', 1) = 'host') END AS server_name FROM shardman.parts p JOIN shardman.repgroups r ON p.rgid = r.id LEFT JOIN shardman.sharded_tables st ON p.rel = st.rel LEFT JOIN pg_foreign_server fs ON r.srvid = fs.oid WHERE st.nspname = 'bookings' ORDER BY table_name, num_part, server_name;
Формат вывода результата: имя таблицы, количество секций в таблице, номер секции и имя сервера:
table_name | total_parts | num_part | server_name --------------------------+-------------+----------+------------------ bookings.bookings | 4 | 0 | connected server bookings.bookings | 4 | 1 | node2 bookings.bookings | 4 | 2 | node3 bookings.bookings | 4 | 3 | node4 bookings.ticket_flights | 4 | 0 | connected server bookings.ticket_flights | 4 | 1 | node2 bookings.ticket_flights | 4 | 2 | node3 bookings.ticket_flights | 4 | 3 | node4 bookings.tickets | 4 | 0 | connected server bookings.tickets | 4 | 1 | node2 bookings.tickets | 4 | 2 | node3 bookings.tickets | 4 | 3 | node4 bookings.boarding_passes | 4 | 0 | connected server bookings.boarding_passes | 4 | 1 | node2 bookings.boarding_passes | 4 | 2 | node3 bookings.boarding_passes | 4 | 3 | node4
22.2.1.6. Сбор статистики #
Для сбора статистики по сегментированным и глобальным таблицам вызовите функцию shardman.global_analyze()
. Сначала эта функция выполняет сбор статистики для всех локальных секций распределённых таблиц на каждом узле, а затем транслирует эту статистику на другие узлы. Для глобальной таблицы будет выполнен сбор статистики на одном выбранном узле, после чего собранная статистика транслируется на все остальные узлы кластера.