Партицирование в Greenplum 7: что нового (2023)

Greenplum 7 — первая версия СУБД, совместимая с секционированными таблицами из PostgreSQL: World DB.

Небольшая предыстория: до PostgreSQL 10 партицирование в PostgreSQL выполнялось в очень ограниченной форме и по сути, было просто вариантом наследования таблиц. Начиная с PostgreSQL 10, мы можем использовать декларативный синтаксис для определения парадигмы разделов.

В рамках слияния с PostgreSQL 12 Greenplum 7 вобрал в себя весь синтаксис PostgreSQL для разбиения таблиц, сохранив при этом синтаксис Greenplum. В результате у Greenplum 7 есть шанс взять лучшее из обоих миров — что именно, обсудим в этой статье.

(Video) GREENPLUM ЧТО ЗА ЗВЕРЬ И КАК ЕГО ПРИРУЧИТЬ / ДМИТРИЙ ПАВЛОВ

Партицирование в Greenplum 7: что нового (2)

Новый синтаксис

Прежде чем начнём разбирать, что нового в Greenplum 7, предлагаю обсудить, что осталось без изменений.

PostgreSQL имеет то же объявление для ключа партицирования, что и Greenplum, — PARTITION BY. Оно же присутствует в Greenplum 7. Также у PostgreSQL есть стратегии разбиения RANGE и LIST, которые Greenplum продолжает поддерживать в новой версии. Но здесь есть важное отличие: Greenplum 7 позволяет определять секционированную таблицу без определения дочерних разделов, например:

CREATE TABLE sales (id int, date date, amt decimal(10,2))DISTRIBUTED BY (id)PARTITION BY RANGE (date);

Команда CREATE TABLE ... PARTITION BY создаёт только родительскую секционированную таблицу без каких-либо дочерних разделов. Дочерние разделы в Greenplum 7 — это таблицы первого класса, которые можно создавать с помощью отдельных команд (их мы рассмотрим в следующих разделах).

Партицирование в Greenplum 7: что нового (3)

«DWHна основеGreenPlum»

Стратегия разделения хеша

Помимо существующих стратегий партицирования RANGE и LIST Greenplum 7 поддерживает партицирование HASH. Эти стратегии работают так же, как и в PostgreSQL. Пример создания хэш-секционированной таблицы и её дочерних разделов:

-- create a tabled partitioned by hash strategyCREATE TABLE sales_by_hour (id int, date date, hour int, amt decimal(10,2))DISTRIBUTED BY (id)PARTITION BY HASH (hour);-- every hash partition modulus must be a factor of the next larger modulusCREATE TABLE sales_by_hour_1 PARTITION OF sales_by_hour FOR VALUES WITH (MODULUS 24, REMAINDER 0);CREATE TABLE sales_by_hour_2 PARTITION OF sales_by_hour FOR VALUES WITH (MODULUS 24, REMAINDER 1);CREATE TABLE sales_by_hour_3 PARTITION OF sales_by_hour FOR VALUES WITH (MODULUS 24, REMAINDER 2);......

Новый DDL

Обсудим основные дополнения Greenplum 7, связанные с DDL.

CREATE TABLE PARTITION OF. Как создать новую таблицу и добавить её в качестве дочернего раздела:

CREATE TABLE jan_sales PARTITION OF sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01');

ALTER TABLE ATTACH PARTITION. Как добавить существующую таблицу в качестве нового дочернего раздела:

CREATE TABLE feb_sales (LIKE sales);ALTER TABLE sales ATTACH PARTITION feb_sales FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');

ALTER TABLE DETACH PARTITION. Как удалить таблицу из иерархии партицирования (без удаления самой таблицы):

ALTER TABLE sales DETACH PARTITION jan_sales;

Новый каталог и вспомогательные функции

Информация о разделах теперь хранится в каталоге pg_partitioned_table и в дополнительных полях pg_class (relispartition и relpartbound). Также мы можем использовать новые вспомогательные функции из основной ветки разработки: pg_partition_ancestors(rel)), pg_partition_root(rel) и pg_partition_tree(rel). При этом старые таблицы каталогов, связанные с партицированием, pg_partition и pg_partition_ruleушли, как и функция pg_partition_def().

-- New catalog for partitioned tablesselect * from pg_partitioned_table where partrelid = 'sales'::regclass; partrelid | partstrat | partnatts | partdefid | partattrs | partclass | partcollation | partexprs-----------+-----------+-----------+-----------+-----------+-----------+---------------+----------- 156181 | r | 1 | 0 | 2 | 3122 | 0 |(1 row)-- A convenient helper routine to check the partition hierarchyselect pg_partition_tree('sales'); pg_partition_tree----------------------------------- (sales,,f,0) (jan_sales,sales,t,1) (sales_1_prt_feb_sales,sales,t,1) (sales_1_prt_mar_sales,sales,t,1)(4 rows)

Новые воркфлоу

Одна из самых важных вещей, которую нужно знать о новых синтаксисах, заключается в том, что они предоставляют рабочие процессы, альтернативные тем, что раньше делали легаси-команды Greenplum. И это не значит, что новый синтаксис стал более сложным. Всё наоборот: новые синтаксисы более простые в использовании. В большинстве случаев с их помощью проще реализовать определённые парадигмы разделов, включая выполнение задач, которые решали старые команды. Ниже мы приведём несколько примеров.

(Video) The Greenplum 7 Beta is OPEN!

Но важно понимать, что новые синтаксисы не заменяют старые. Поэтому вы должны хорошо понимать обе группы синтаксисов (особенно их различия), чтобы подбирать наиболее подходящие команды под свои нужды.

Создание дочернего раздела вместе с родительским

Greenplum может создавать дочерние разделы вместе с родительской таблицей:

CREATE TABLE sales (id int, date date, amt decimal(10,2))DISTRIBUTED BY (id)PARTITION BY RANGE (date)(PARTITION jan_sales START ('2023-01-01') END ('2023-02-01'),PARTITION feb_sales START ('2023-02-01') END ('2023-03-01'),DEFAULT PARTITION other_sales);

В PostgreSQL нет аналогичной команды. Вместо этого сначала создаётся родительская секционированная таблица, а затем отдельно добавляются дочерние секции:

CREATE TABLE sales (id int, date date, amt decimal(10,2))DISTRIBUTED BY (id)PARTITION BY RANGE (date);-- Add partition individuallyCREATE TABLE jan_sales PARTITION OF sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01');CREATE TABLE feb_sales PARTITION OF sales FOR VALUES FROM ('2023-02-01') TO ('2023-03-01');CREATE TABLE other_sales PARTITION OF sales DEFAULT;

Создание и добавление дочерних разделов

ALTER TABLE... ADD PARTITION и CREATE TABLE... PARTITION OF одновременно создают и добавляют новую дочернюю таблицу. Однако, поскольку CREATE TABLE PARTITION OF является командой CREATE TABLE, в отличие от ADD PARTITION, которая является подкомандой ALTERTABLE, с помощью CREATE TABLE ... PARTITION OF можно указать дополнительные параметры создания таблиц. ADD PARTITION обычно наследует только то, что есть в родительской таблице.

-- CREATE TABLE allows you to specify more optionsCREATE TABLE jan_sales PARTITION OF sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01')USING ao_row WITH(compresstype=zlib);-- ADD PARTITION does the creation but have to specify options in separate commandsALTER TABLE sales ADD PARTITION jan_sales START ('2023-01-01') END ('2023-02-01');ALTER TABLE sales_1_prt_jan_sales SET ACCESS METHOD ao_row;ALTER TABLE sales_1_prt_jan_sales SET WITH (compresstype=zlib);

Поменять местами существующий раздел с другой таблицей

Команда EXCHANGE PARTITION в легаси-синтаксисе заменяет существующий дочерний раздел обычной таблицей. С новым синтаксисом можно просто использовать DETACH PARTITION и ATTACHPARTITION, чтобы добиться того же. Внутри Greenplum 7 выполняется DETACH, а затем ATTACHPARTITION с некоторой заменой имен.

-- 1. Using EXCHANGE PARTITIONALTER TABLE sales EXCHANGE jan_sales WITH TABLE jan_sales_new; -- 2. Using ATTACH PARTITIONALTER TABLE sales DETACH PARTITION jan_sales;ALTER TABLE sales ATTACH PARTITION jan_sales_new;

Удалить дочерний раздел

Раньше было довольно сложно удалить дочерний раздел, не удаляя таблицу. В устаревшем Greenplum есть только команда ALTER TABLE ... DROP PARTITION, которая также удаляет таблицу. Сначала вам нужно создать фиктивную таблицу, заменить раздел, который вы хотите удалить, на фиктивную таблицу, а затем удалить замененный раздел. Теперь с помощью ALTER TABLE ... DETACH PARTITION можно легко выполнить ту же задачу:

-- Lengthy operations to remove an unwanted child partition w/o dropping it:CREATE TABLE dummy (LIKE sales);ALTER TABLE sales EXCHANGE PARTITION archived_sales WITH dummy;ALTER TABLE sales DROP PARTITION archived_sales;DROP TABLE dummy;-- Can just "DETACH PARTITION" now:ALTER TABLE sales DETACH PARTITION archived_sales;

ALTER TABLE ... DROP PARTITION по сути выполняет ту же задачу, что и DROP TABLE. Тогда почему ALTER TABLE ... DROP PARTITION все ещё существует? Это связано с тем, что два синтаксиса по-разному обрабатывают имя таблицы.

Разделить дочерний раздел

SPLIT PARTITION — специальная команда, которая выполняет интересную задачу: разделяет конечный раздел и создаёт из него два раздела. Это ещё один синтаксис без простой альтернативы в PostgreSQL. Вы должны вручную отсоединить раздел и добавить два раздела, соответствующих разделённым диапазонам.

Кейс

Легаси-синтаксис

Альтернативный новый/ существующий синтаксис

Создать дочерний раздел вместе с родительским

CREATE TABLE ... (PARTITION ...)

CREATE TABLE ... PARTITION BY and CREATE TABLE ... PARTITION OF

Создать и добавить раздел

ALTER TABLE ... ADD PARTITION

CREATE TABLE ... PARTITION OF

Замените существующий дочерний раздел обычной таблицей

ALTER TABLE ... EXCHANGE PARTITION

ALTER TABLE ... DETACH PARTITIONand ATTACH PARTITION

Удалить раздел

ALTER TABLE ... DROP PARTITION

DROP TABLE

Разделить раздел

ALTER TABLE ... SPLIT PARTITION

DETACH partition and ATTACH new ones separately

Другие отличия

Имя раздела vs. имя таблицы

Исторически сложилось так, что имя, которое указывается в DDL Greenplum, является так называемым «именем раздела» и не совпадает с именем таблицы. По сути, Greenplum добавляет к имени дочерней таблицы специальный префикс, соответствующий родительскому разделу. Например, при использовании устаревшего синтаксиса для добавления разделов:

(Video) vForum 2021. Greenplum: быстро, надёжно, параллельно. В чём подвох?

CREATE TABLE sales (id int, date date, amt decimal(10,2))DISTRIBUTED BY (id)PARTITION BY RANGE (date)(PARTITION jan_sales START ('2023-01-01') END ('2023-02-01'));ALTER TABLE sales ADD PARTITION feb_sales START ('2023-02-01') END ('2023-03-01');\d+ sales Partitioned table "public.sales" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description--------+---------------+-----------+----------+---------+---------+--------------+------------- id | integer | | | | plain | | date | date | | | | plain | | amt | numeric(10,2) | | | | main | |Partition key: RANGE (date)Partitions: sales_1_prt_feb_sales FOR VALUES FROM ('2023-02-01') TO ('2023-03-01'), sales_1_prt_jan_sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01')Distributed by: (id)Access method: heap

У дочерних разделов есть префикс sales_1_prt_ к именам, которые мы для них указываем (jan_sales и feb_sales). Новый синтаксис просто обрабатывает имена, указанные в качестве имени таблицы:

CREATE TABLE sales (id int, date date, amt decimal(10,2))DISTRIBUTED BY (id)PARTITION BY RANGE (date);CREATE TABLE jan_sales PARTITION OF salesFOR VALUES FROM ('2023-01-01') TO ('2023-02-01');CREATE TABLE feb_sales (LIKE sales);ALTER TABLE sales ATTACH PARTITION feb_salesFOR VALUES FROM ('2024-02-01') TO ('2024-03-01'); \d+ sales Partitioned table "public.sales" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description--------+---------------+-----------+----------+---------+---------+--------------+------------- id | integer | | | | plain | | date | date | | | | plain | | amt | numeric(10,2) | | | | main | |Partition key: RANGE (date)Partitions: feb_sales FOR VALUES FROM ('2024-02-01') TO ('2024-03-01'), jan_sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01')Distributed by: (id)Access method: heap

Однако это различие согласуется между старым и новым синтаксисами. Например, нам не нужно указывать префикс при использовании устаревшего синтаксиса DROP PARTITION. Но нужно, еслииспользуем раздел DETACH:

-- Assuming we have the 'sales' partition with Jan and Feb -- child partitions, created using legacy syntax.\d+ sales Partitioned table "public.sales" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description--------+---------------+-----------+----------+---------+---------+--------------+------------- id | integer | | | | plain | | date | date | | | | plain | | amt | numeric(10,2) | | | | main | |Partition key: RANGE (date)Partitions: sales_1_prt_feb_sales FOR VALUES FROM ('2023-02-01') TO ('2023-03-01'), sales_1_prt_jan_sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01')Distributed by: (id)Access method: heap-- drop partition 'jan_sales', no problemALTER TABLE sales DROP PARTITION jan_sales;-- but couldn't detach, because there's no table named 'feb_sales'ALTER TABLE sales DETACH PARTITION feb_sales;ERROR: relation "feb_sales" does not exist-- have to specify full name using DETACHALTER TABLE sales DETACH PARTITION sales_1_prt_feb_sales;

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

Для удобства воспользуемся таблицей, чтобы наглядно увидеть разницу:

Синтаксис

Добавлять префикс или нет

Старый или новый

ADD PARTITION

да

Legacy

DROP PARTITION

да

Legacy

EXCHANGE PARTITION

да

Legacy

SPLIT PARTITION

да

Legacy

CREATE TABLE (PARTITION ...)

да

Legacy

CREATE TABLE (EVERY ...)

да

Legacy

CREATE TABLE ... PARTITION OF

нет

New

ATTACH PARTITION

нет

New

DETACH PARTITION

нет

New

START|END vs FROM|TO

Из примеров SQL, которые были показаны ранее, вы, вероятно, заметили, что в новом синтаксисе также есть другие ключевые слова для определения раздела диапазона: FOR VALUES FROM ... TO .... Легаси-синтаксис Greenplum имеет START ... END (). Оба определения работают только в соответствующих легаси или новых DDL:

-- Both these work:ALTER TABLE sales ADD PARTITION mar_sales START ('2023-03-01') END ('2023-03-31');CREATE TABLE mar_sales PARTITION OF sales FOR VALUES FROM ('2023-03-01') TO ('2023-03-31');-- But these won't:ALTER TABLE sales ADD PARTITION mar_sales FOR VALUES FROM ('2023-03-01') TO ('2023-03-31');CREATE TABLE mar_sales PARTITION OF sales START ('2023-03-01') END ('2023-03-31');

В легаси-синтаксисе также есть ключевые слова EXCLUSIVE и INCLUSIVE для разделения диапазонов. В PostgreSQL такого нет, и начальная граница всегда включающая, а конечная — исключающая. Greenplum 7 поддерживает EXCLUSIVE|INCLUSIVE, неявно добавляя «+1» к начальному или конечному диапазону. В результате они работают с типами данных, у которых подходящий оператор «+». Например, integer и timestamp, но float или text.

ALTER TABLE sales ADD PARTITION mar_salesSTART ('2023-03-01') INCLUSIVE END ('2023-03-31') INCLUSIVE;

Ограниченная блокировка в ATTACH PARTITION

ATTACH PARTITION требует монопольной блокировки общего обновления только для родительской таблицы. Этот тип блокировки считается менее строгим и не конфликтует со многими другими запросами, включая SELECT, INSERT и иногда UPDATE. По сути, это значит, что только до Greenplum 7 можно добавлять раздел в иерархию разделов без нарушения обычных операций выполнения запросов к разделу (и наоборот). Например:

-- Assuming there's long-running insertINSERT INTO sales SELECT * FROM ext_sales_data;-- This will be blockedALTER TABLE sales ADD PARTITION march_sales START ('2023-03-01') END ('2023-04-01');-- This will go throughALTER TABLE sales ATTACH PARTITION march_sales FOR VALUES FROM ('2023-03-01') TO ('2023-04-01');

Ограничения раздела и ограничения проверки

Границы разделов больше не представляются в виде CHECK ограничений. Ограничения разделов теперь — отдельная концепция.

-- same partition definition in Greenplum 6 and 7-- Greenplum 6\d+ sales_1_prt_jan_sales Table "public.sales_1_prt_jan_sales" Column | Type | Modifiers | Storage | Stats target | Description--------+---------------+-----------+---------+--------------+------------- id | integer | | plain | | date | date | | plain | | amt | numeric(10,2) | | main | |Check constraints: "sales_1_prt_jan_sales_check" CHECK (date >= '2023-01-01'::date AND date < '2023-02-01'::date)Inherits: salesDistributed by: (id)-- Greenplum 7\d+ jan_sales Table "public.jan_sales" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description--------+---------------+-----------+----------+---------+---------+--------------+------------- id | integer | | | | plain | | date | date | | | | plain | | amt | numeric(10,2) | | | | main | |Partition of: sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01')Partition constraint: ((date IS NOT NULL) AND (date >= '2023-01-01'::date) AND (date < '2023-02-01'::date))Distributed by: (id)

PARTITION BY с несколькими столбцами

Разбиение списка на несколько столбцов больше не поддерживается. В качестве обходного пути вы можете создать составной тип и использовать его в качестве ключа разделения, например:

(Video) Greenplum v7 Alpha Feature Demo: UPSERT

-- This is no longer working:CREATE TABLE foo (a int, b int, c int) PARTITION BY list (b,c);ERROR: cannot use "list" partition strategy with more than one column-- Alternatively:CREATE TYPE partkey as (b int, c int);CREATE TABLE foo (a int, b int, c int)PARTITION BY LIST ((row(b, c)::partkey));

Коротко о главном

В статье рассмотрели основные отличия Greenplum 7 от предыдущих версий СУБД. А также разобрали, на что стоит обратить внимание при работе с легаси- и новым синтаксисом.

Партицирование в Greenplum 7: что нового (4)

«DWHна основеGreenPlum»

Videos

1. Связь GreenPlum и PostgreSQL
(Слёрм)
2. Как готовить данные в Greenplum®
(Yandex Cloud)
3. Дмитрий Немчин, Tinkoff - Greenplum worst practies
(IT's Tinkoff)
4. Вебинар - Greenplum: 2020 update
(Arenadata)
5. Optimizing Performance of Greenplum Database
(Greenplum Database)
6. Дмитрий Павлов «Greenplum: Быстро, параллельно, консистентно»
(DotNetRu)

References

Top Articles
Latest Posts
Article information

Author: Moshe Kshlerin

Last Updated: 15/04/2023

Views: 5949

Rating: 4.7 / 5 (57 voted)

Reviews: 88% of readers found this page helpful

Author information

Name: Moshe Kshlerin

Birthday: 1994-01-25

Address: Suite 609 315 Lupita Unions, Ronnieburgh, MI 62697

Phone: +2424755286529

Job: District Education Designer

Hobby: Yoga, Gunsmithing, Singing, 3D printing, Nordic skating, Soapmaking, Juggling

Introduction: My name is Moshe Kshlerin, I am a gleaming, attractive, outstanding, pleasant, delightful, outstanding, famous person who loves writing and wants to share my knowledge and understanding with you.