В 7-м релизе Greenplum, о котором мы писали здесь и здесь, вышло много изменений. Одним из них стал целый набор обновленных функций, связанных с партиционированием таблиц. Читайте далее, как Greenplum стал еще на шаг ближе к PostgreSQL и что изменилось в части синтаксиса SQL-запросов.
Управление разделами в Greenplum и PostgreSQL
Хотя Greenplum и основан на PostgreSQL, структура хранения данных в этих СУБД немного отличается. Однако, в 7-м релизе Greenplum движется навстречу PostgreSQL в части разделения таблиц. В PostgreSQL до версии 10 партиционирование таблиц выполнялось весьма ограничено, представляя собой просто сценарий наследования. В PostgreSQL 10 и выше пользователи могли использовать декларативный синтаксис для определения своей парадигмы разделов. В свою очередь, Greenplum давно поддерживает партиционирование таблиц. Поэтому в 7-м выпуске в рамках приближения к PostgreSQL 12, Greenplum поддерживает этот обновленный синтаксис, а также собственные прежние конструкции. Примечательно, что регрессионные тесты выявили недостаток нового синтаксиса, который пришлось устранять, о чем мы рассказываем в новой статье.
Предложение PARTITION BY для объявления ключа раздела осталось неизменным в Greenplum 7, как и в PostgreSQL. Аналогично, PostgreSQL и Greenplum поддерживают стратегии разделения RANGE и LIST. Также Greenplum 7 теперь поддерживает стратегию HASH, которая работает так же, как и в PostgreSQL.
Еще Greenplum 7 позволяет определять партиционированную таблицу без определения дочерних разделов. Чтобы позволить дата-инженеру эффективно управлять партиционированными таблицами, в Greenplum 7 добавлено новое ключевое слово ONLY, которое позволяет избежать рекурсии при изменении многораздельной таблицы с помощью команды ALTER TABLE. Без ключевого слова ONLY команда ALTER TABLE будет рекурсивно выполняться во всех дочерних разделах партиционированной таблицы. Но такая вложенность не всегда нужна, например, когда необходимо изменить метод доступа к будущим разделам, без применения к существующим. Предположим, таблица продаж (sales) является таблицей кучи и имеет несколько разделов. Нужно поменять метод доступа только к ней самой, без влияния на вложенные структуры. Преобразование таблицы кучи в AO-таблицу представляет собой изменение метода доступа к ней с кучи на ao_row:
ALTER TABLE ONLY sales SET ACCESS METHOD ao_row;
Про новые возможности изменения таблицы с помощью команды ALTER TABLE, которые стали доступны в 7-ой версии MPP-СУБД, читайте в нашей новой статье.
Также в Greenplum 7 можно указать ключевое слово ONLY для команды выдачи привилегий GRANT/REVOKE. Исторически поведение Greenplum при этой команде в родительской многораздельной таблице рекурсивно выполнялось в ее дочерних разделах, что отличается от PostgreSQL. Повысить гибкость и исключить такую рекурсию позволяет добавление опции ONLY при выдаче прав. Например, для доступа к партиционированной таблице sales нужны 2 роли с правами на чтение: одна для существующих и одна для будущих разделов. Выдача привилегий для будущих разделов родительской таблицы выглядит так:
GRANT SELECT ON ONLY sales TO role_that_can_read_only_future_partitions;
Чтобы ограничить права на доступ к будущим разделам, отзовем выданные разрешения на родительскую таблицу:
GRANT SELECT ON sales TO roles_that_can_read_only_existing_partitions; REVOKE SELECT ON ONLY sales FROM roles_that_can_read_only_existing_partitions;
Обычно создание новой таблицы в качестве дочернего раздела наследует все свойства родительской. Например, выражение SPLIT PARTITION создает новые дочерние разделы из существующего дочернего, но новые разделы наследуют не исходную родительскую, а уже дочернюю таблицу. Если же нужно не создать новую таблицу, а просто присоединить существующую таблицу в качестве дочернего раздела, ее исходные свойства обычно сохраняются после присоединения. Для присоединения внешней таблицы к дочернему разделу используется выражение EXCHANGE PARTITION. Но в Greenplum 7 поведение этой команды похоже на ATTACH PARTITION: EXCHANGE PARTITION не требует, чтобы у будущей таблицы раздела был тот же владелец и индекс, что и у родительской таблицы. При отсутствии индекса у присоединяемого раздела он будет создан. Однако, EXCHANGE PARTITION теперь требует, чтобы у будущего раздела было ограничение, которое есть у его родителя. ATTACH PARTITION требует монопольной блокировки общего обновления только для родительской таблицы, что стало менее строгим по сравнению с прошлой версией и не конфликтует со многими другими запросами, включая SELECT, INSERT и UPDATE. Поэтому в Greenplum 7 стало возможным добавлять разделы в иерархию разделов, не нарушая выполнение многих обычных запросов к разделу.
Таким образом, основными дополнениями в Greenplum 7 являются следующие новые DDL-команды для разделов, как в PostgreSQL:
- CREATE TABLE PARTITION OF — для создания новой таблицы и добавления ее в качестве нового дочернего раздела;
- ALTER TABLE ATTACH PARTITION – для добавления существующей таблицы в качестве нового дочернего раздела;
- ALTER TABLE DETACH PARTITION – для удаления таблицы из иерархии партиционирования без удаления самой таблицы.
Информация о разделах теперь хранится в вышестоящем каталоге 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().
Таким образом, новый синтаксис управления разделами партиционированных таблиц в GP 7 менее специализирован, чтобы упростить реализацию сложных иерархий и работу с ними. Отличия новых команд от прежнего синтаксиса показаны в таблице.
Сценарий применения |
Старый синтаксис |
Обновления в Greenplum 7 |
Создать дочерний раздел вместе с родительским |
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 PARTITION and ATTACH PARTITION |
Удалить раздел |
ALTER TABLE … DROP PARTITION |
DROP TABLE |
Разделить раздел |
ALTER TABLE … SPLIT PARTITION |
DETACH partition and ATTACH new ones separately |
Еще несколько изменений в GP 7
Исторически сложилось так, что имя, которое указывается в DDL-команде создания раздела Greenplum не совпадает с именем самой таблицы. По сути, Greenplum добавляет к имени дочерней таблицы специальный префикс, соответствующий родительскому разделу. Новый синтаксис просто обрабатывает имена, указанные как имя таблицы. Например, не нужно указывать префикс при использовании устаревшего синтаксиса DROP PARTITION. Но он понадобится при использовании выражения DETACH PARTITION. Поэтому рекомендуется для одной и той же многораздельной таблицы придерживаться либо нового, либо прежнего синтаксиса, чтобы избежать двусмысленности.
Команда |
Добавление префикса |
Новый или старый синтаксис |
ADD PARTITION |
Да |
Старый |
DROP PARTITION |
Да |
Старый |
EXCHANGE PARTITION |
Да |
Старый |
SPLIT PARTITION |
Да |
Старый |
CREATE TABLE (PARTITION …) |
Да |
Старый |
CREATE TABLE (EVERY …) |
Да |
Старый |
CREATE TABLE … PARTITION OF |
Нет |
Новый |
ATTACH PARTITION |
Нет |
Новый |
DETACH PARTITION |
Нет |
Новый |
Новый синтаксис также имеет другие ключевые слова для определения раздела диапазона: FOR VALUES FROM … TO …., что работает аналогично прежнему START … END (). Оба определения поддерживаются только в соответствующих новых или старых DDL-командах. В устаревшем синтаксисе также есть ключевые слова EXCLUSIVE и INCLUSIVE для разделения диапазонов. В PostgreSQL такого нет: начальная граница всегда включающая, а конечная — исключающая. Greenplum 7 продолжает поддерживать EXCLUSIVE|INCLUSIVE, неявно добавляя «+1» к начальному или конечному диапазону. Поэтому ключевые слова теперь работают только с типами данных, над которыми можно выполнять фактическое сложение, например, целое число и отметка времени, но не числа с плавающей запятой или текст.
Границы разделов больше не представлены в виде ограничений CHECK. Ограничения на разделы теперь являются совершенно отдельной концепцией, а разделение таблицы на несколько столбцов с помощью PARTITION BY больше не поддерживается. В качестве обходного пути можно создать составной тип и использовать его в качестве ключа разделения.
Узнайте больше про администрирование и эксплуатацию Greenplum с Arenadata DB для эффективного хранения и аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники