Важно понимать поведение рекурсии и наследования, чтобы получить правильную парадигму партицирования. Как и в предыдущей статье, в этой разбираемся с новыми командами в GreenPlum 7 и изменениями в легаси-командах.
![](https://habrastorage.org/getpro/habr/upload_files/f46/c74/bcc/f46c74bccb04a3fcc684a4f5dc47e419.png)
Ключевое слово ONLY
Всегда можно указать ключевое слово ONLY
, если не предполагается рекурсия. Допустим, мы хотим изменить метод доступа к будущим разделам, но не хотим, чтобы он применялся к существующим. Можем сделать следующее:
-- Assuming partitioned table 'sales' and all -- of its child partitions are heap tables. ALTER TABLE ONLY sales SET ACCESS METHOD ao_row;
Для секционированной таблицы зададим подходящий способ доступа:
\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: jan_sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01') Distributed by: (id) Access method: ao_row
При этом существующий дочерний раздел приложения не будет затронут:
\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) Access method: heap
GRANT ONLY|REVOKE ONLY
Также в Greenplum 7 можем указать ключевое слово ONLY
для GRANT/REVOKE
, которых нет в PostgreSQL. Обратите внимание, что исторически у Greenplum было такое поведение, при котором GRANT|REVOKE
в родительской секционированной таблице рекурсивно выполнялось в её дочерних разделах. Greenplum 7 придерживается такого же поведения, но добавляет опцию ONLY
, чтобы обеспечить гибкость, если вы не хотите выполнять рекурсию.
Простой пример использования:
-- Let's say at some point you want two roles with read permission -- on our 'sale' partitioned table, but one for existing partitions -- and another for future partitions. -- 1. Grant only on the parent table for just future partitions. GRANT SELECT ON ONLY sales TO role_that_can_read_only_future_partitions; -- 2. W/o "ONLY", this will grant for all existing partitions. -- Then, revoke only for parent to limit permission for 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
![](https://habrastorage.org/getpro/habr/upload_files/206/691/0ad/2066910ad2a7f753101dcc8cbcc832e9.jpg)
Создание новой дочерней таблицы
Как правило, при создании новой таблицы в качестве дочернего раздела наследуются все свойства родительской таблицы. Начнём с таблицы sales
:
CREATE TABLE sales (id int, date date, amt decimal(10,2)) USING ao_row DISTRIBUTED BY (id) PARTITION BY RANGE (date);
Можем использовать два типа синтаксиса для создания новой таблицы в качестве дочернего раздела:
-- Create child partition using the new Greenplum 7 syntax CREATE TABLE jan_sales PARTITION OF sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01'); -- Create child partition using the legacy syntax ALTER TABLE sales ADD PARTITION feb_sales START ('2023-02-01') END ('2023-03-01');
Оба дочерних раздела унаследуют метод доступа к родительской таблице, ориентированный на добавление строк (ao_row
):
\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: jan_sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01'), sales_1_prt_feb_sales FOR VALUES FROM ('2023-02-01') TO ('2023-03-01') Distributed by: (id) Access method: ao_row \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)) Compression Type: None Compression Level: 0 Block Size: 32768 Checksum: t Distributed by: (id) Access method: ao_row \d+ sales_1_prt_feb_sales Table "public.sales_1_prt_feb_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-02-01') TO ('2023-03-01') Partition constraint: ((date IS NOT NULL) AND (date >= '2023-02-01'::date) AND (date < '2023-03-01'::date)) Compression Type: None Compression Level: 0 Block Size: 32768 Checksum: t Distributed by: (id) Access method: ao_row
SPLIT PARTITION
SPLIT PARTITION
— особенный кейс, когда новые дочерние разделы создаются из существующего дочернего раздела. В этом случае новые разделы будут наследовать не родительскую секционированную таблицу, а разделенную дочернюю. Предположим, по какой-то причине мы сделали так, чтобы раздел feb_sales
в нашем примере имел метод доступа, отличный от родительского:
ALTER TABLE sales_1_prt_feb_sales SET ACCESS METHOD ao_column;
Теперь разделим его на два новых раздела:
ALTER TABLE sales SPLIT PARTITION feb_sales AT ('2023-02-15') INTO (partition feb_first_half, partition feb_second_half);
Теперь новые разделы будут иметь метод доступа, отличный от родительского (обратите внимание, что исходный раздел feb_sales
исчез):
\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: jan_sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01'), sales_1_prt_feb_first_half FOR VALUES FROM ('2023-02-01') TO ('2023-02-15'), sales_1_prt_feb_second_half FOR VALUES FROM ('2023-02-15') TO ('2023-03-01') Distributed by: (id) Access method: ao_row \d+ sales_1_prt_feb_first_half Table "public.sales_1_prt_feb_first_half" Column | Type | Collation | Nullable | Default | Storage | Stats target | Compression Type | Compression Level | Block Size | Description --------+---------------+-----------+----------+---------+---------+--------------+------------------+-------------------+------------+------------- id | integer | | | | plain | | none | 0 | 32768 | date | date | | | | plain | | none | 0 | 32768 | amt | numeric(10,2) | | | | main | | none | 0 | 32768 | Partition of: sales FOR VALUES FROM ('2023-02-01') TO ('2023-02-15') Partition constraint: ((date IS NOT NULL) AND (date >= '2023-02-01'::date) AND (date < '2023-02-15'::date)) Distributed by: (id) Access method: ao_column Options: blocksize=32768, compresslevel=0, compresstype=none, checksum=true
Это поведение наследования в SPLIT PARTITION
остаётся таким же, как и в Greenplum 6.
Присоединение существующей таблицы
Рассмотрим кейс, когда мы не создаём новую таблицу, а просто присоединяем существующую таблицу в качестве дочернего раздела. В этом случае исходные свойства таблицы сохраняются после того, как она становится дочерним разделом. Предположим, изначально у нас была таблица recent_sales
, которую мы продолжаем часто обновлять, и по умолчанию она использует heap
access-метод:
CREATE TABLE recent_sales (id int, date date, amt decimal(10,2)); \d+ recent_sales; Table "public.recent_sales" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------------+-----------+----------+---------+---------+--------------+------------- id | integer | | | | plain | | date | date | | | | plain | | amt | numeric(10,2) | | | | main | | Distributed by: (id) Access method: heap
Мы хотим присоединить эту таблицу к секционированной таблице sales
. После этого она сохранит свои исходные свойства, включая метод доступа:
ALTER TABLE sales ATTACH PARTITION recent_sales FOR VALUES FROM ('2023-12-01') TO ('2030-12-31'); \d+ recent_sales Table "public.recent_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-12-01') TO ('2030-12-31') Partition constraint: ((date IS NOT NULL) AND (date >= '2023-12-01'::date) AND (date < '2030-12-31'::date)) Distributed by: (id) Access method: heap
EXCHANGE PARTITION
Ещё один кейс — когда EXCHANGE PARTITION
прикрепляет существующую внешнюю таблицу к дочернему разделу. В Greenplum 7 есть несколько изменений, как теперь новый дочерний раздел наследует свойства таблицы.
Как упоминалось в предыдущей статье, EXCHANGE PARTITION
в Greenplum 7 состоит из DETACHPARTITION
и ATTACH PARTITION
. В результате EXCHANGE PARTITION
больше похож на ATTACH PARTITION
по поведению наследования. Вот подробный список:
-
Владелец таблицы:
EXCHANGE PARTITION
не требует, чтобы у будущей таблицы разделов был тот же владелец, что и у родительской таблицы. -
Индекс:
EXCHANGE PARTITION
не требует, чтобы будущий раздел имел тот же индекс, что и родительский. Команда создаст его, если он отсутствует. -
Ограничение таблицы:
EXCHANGE PARTITION
требует, чтобы у будущего раздела были все ограничения, которые есть у его родителя.
Заключение
В общем, большинство команд ALTER TABLE
и GRANT|REVOKE
будут возвращаться к своим дочерним разделам, если только не указано ключевое слово ONLY
. И будет ли наследоваться новый дочерний раздел или нет, зависит от того, создан он или присоединен. Если он создан, он будет наследовать от родителя, в противном случае он сохраняет свои собственные исходные свойства.
![](https://habrastorage.org/getpro/habr/upload_files/206/691/0ad/2066910ad2a7f753101dcc8cbcc832e9.jpg)
ссылка на оригинал статьи https://habr.com/ru/articles/727076/
Добавить комментарий