Перейти к содержимому
Последнее обновление

Временный раздел

Временный раздел — это тип раздела в таблице Doris с разделами, независимый от основных разделов. Обычные запросы к нему не обращаются: доступ к нему необходимо явно указывать с помощью специального синтаксиса. Временные разделы используются главным образом для атомарного переключения данных и изменения структуры разделов без влияния на текущие операции чтения и записи.

Сценарии использования​

СценарийОписаниеКлючевая возможность
Атомарная перезаписьПерезапись данных раздела без промежутка между удалением старых данных и загрузкой новыхАтомарная замена с помощью REPLACE PARTITION
Изменение числа бакетовТекущее число бакетов существующего раздела неоптимально и требует измененияЗадание нового числа бакетов для временного раздела с последующей заменой
Объединение / разбиение разделовИзменение размера разделов путём объединения нескольких разделов в один или разбиения одного большого раздела на несколькоПерераспределение данных с помощью INSERT INTO с последующей заменой

Совет: об атомарной перезаписи таблицы без разделов см. в документации по Replace Table.

Основные ограничения​

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

  • Столбцы разбиения временного раздела совпадают со столбцами разбиения основных разделов и не могут быть изменены.
  • Диапазоны всех временных разделов не должны пересекаться друг с другом.
  • Диапазоны временного раздела и основного раздела могут пересекаться.
  • Имя временного раздела не может совпадать с именем любого основного или другого временного раздела.

Обзор порядка действий​

Типичный процесс состоит из следующих четырёх шагов:

  1. Добавьте временный раздел (укажите диапазон / перечисляемые значения / число бакетов)
  2. Загрузите данные во временный раздел (INSERT INTO / Stream Load / Broker Load / Routine Load)
  3. Замените основной раздел (REPLACE PARTITION, атомарная операция)
  4. (Необязательно) Удалите неиспользуемые временные разделы

Добавление временного раздела​

Для создания временного раздела используйте оператор ALTER TABLE ADD TEMPORARY PARTITION. Поддерживаются разделы Range и List; число реплик и правило распределения по бакетам можно задавать независимо.

-- Range partition: LESS THAN form
ALTER TABLE tbl1 ADD TEMPORARY PARTITION tp1 VALUES LESS THAN("2020-02-01");

-- Range partition: fixed-interval form
ALTER TABLE tbl2 ADD TEMPORARY PARTITION tp1 VALUES [("2020-01-01"), ("2020-02-01"));

-- Range partition: custom replica count and bucketing
ALTER TABLE tbl1 ADD TEMPORARY PARTITION tp1 VALUES LESS THAN("2020-02-01")
("replication_num" = "1")
DISTRIBUTED BY HASH(k1) BUCKETS 5;

-- List partition: single-column enumeration
ALTER TABLE tbl3 ADD TEMPORARY PARTITION tp1 VALUES IN ("Beijing", "Shanghai");

-- List partition: multi-column enumeration
ALTER TABLE tbl4 ADD TEMPORARY PARTITION tp1 VALUES IN ((1, "Beijing"), (1, "Shanghai"));

-- List partition: custom replica count and bucketing
ALTER TABLE tbl3 ADD TEMPORARY PARTITION tp1 VALUES IN ("Beijing", "Shanghai")
("replication_num" = "1")
DISTRIBUTED BY HASH(k1) BUCKETS 5;

Загрузка данных во временный раздел​

Синтаксис указания временного раздела немного различается в зависимости от способа загрузки:

-- INSERT INTO
INSERT INTO tbl TEMPORARY PARTITION(tp1, tp2, ...) SELECT ...;
# Stream Load
curl --location-trusted -u root: \
-H "label:123" \
-H "temporary_partitions: tp1, tp2, ..." \
-T testData \
http://host:port/api/testDb/testTbl/_stream_load
-- Broker Load
LOAD LABEL example_db.label1
(
DATA INFILE("hdfs://hdfs_host:hdfs_port/user/palo/data/input/file")
INTO TABLE my_table
TEMPORARY PARTITION (tp1, tp2, ...)
...
)
WITH BROKER hdfs ("username"="hdfs_user", "password"="hdfs_password");

-- Routine Load
CREATE ROUTINE LOAD example_db.test1 ON example_tbl
COLUMNS(k1, k2, k3, v1, v2, v3 = k1 * 100),
TEMPORARY PARTITIONS(tp1, tp2, ...),
WHERE k1 > 100
PROPERTIES (...)
FROM KAFKA (...);

Запрос данных из временного раздела​

Обычные запросы SQL не обращаются к временным разделам. Их необходимо явно указывать с помощью ключевого слова TEMPORARY PARTITION:

SELECT ... FROM
tbl1 TEMPORARY PARTITION(tp1, tp2, ...)
JOIN
tbl2 TEMPORARY PARTITION(tp1, tp2, ...)
ON ...
WHERE ...;

Замена основного раздела​

Для атомарной замены основных разделов временными используйте ALTER TABLE REPLACE PARTITION.

-- Equal-count replacement
ALTER TABLE tbl1 REPLACE PARTITION (p1) WITH TEMPORARY PARTITION (tp1);

-- Many-to-many replacement
ALTER TABLE tbl1 REPLACE PARTITION (p1, p2) WITH TEMPORARY PARTITION (tp1, tp2, tp3);

-- Replace with explicit parameters
ALTER TABLE tbl1 REPLACE PARTITION (p1, p2) WITH TEMPORARY PARTITION (tp1, tp2)
PROPERTIES (
"strict_range" = "false",
"use_temp_partition_name" = "true"
);

Параметры замены​

ПараметрЗначение по умолчаниюОписание
strict_rangetrueОпределяет, насколько строго должны совпадать диапазоны / перечисляемые значения разделов до и после замены (см. ниже)
use_temp_partition_namefalseОпределяет имена основных разделов после замены

strict_range​

  • Раздел Range:
    • true: Объединение диапазонов заменяемых основных разделов должно в точности совпадать с объединением диапазонов временных разделов, используемых для замены.
    • false: Достаточно, чтобы после замены новые основные разделы не пересекались друг с другом.
  • Раздел List: всегда true. Объединение перечисляемых значений заменяемых основных разделов должно в точности совпадать с объединением перечисляемых значений временных разделов, используемых для замены.

Пример 1: объединения диапазонов совпадают (замена разрешена)

-- Ranges (=> union) of partitions p1, p2, p3 to be replaced:
[10, 20), [20, 30), [40, 50) => [10, 30), [40, 50)

-- Ranges (=> union) of replacement partitions tp1, tp2:
[10, 30), [40, 45), [45, 50) => [10, 30), [40, 50)

-- The unions are equal, so tp1 and tp2 can replace p1, p2, and p3.

Пример 2: объединения диапазонов различаются (зависит от strict_range)

-- Range (=> union) of partition p1 to be replaced:
[10, 50) => [10, 50)

-- Ranges (=> union) of replacement partitions tp1, tp2:
[10, 30), [40, 50) => [10, 30), [40, 50)

-- strict_range = true: replacement is rejected.
-- strict_range = false: if the resulting [10, 30) and [40, 50) do not overlap with other formal partitions, the replacement is allowed.

Пример 3: объединения перечисляемых значений одного столбца в разделах List совпадают

-- Enumerated values (=> union) of partitions p1, p2 to be replaced:
(1, 2, 3), (4, 5, 6) => (1, 2, 3, 4, 5, 6)

-- Enumerated values (=> union) of replacement partitions tp1, tp2, tp3:
(1, 2, 3), (4), (5, 6) => (1, 2, 3, 4, 5, 6)

-- The unions are equal, so tp1, tp2, and tp3 can replace p1 and p2.

Пример 4: объединения перечисляемых значений нескольких столбцов в разделах List совпадают

-- Enumerated values (=> union) of partitions p1, p2, p3 to be replaced:
(("1","beijing"), ("1", "shanghai")),
(("2","beijing"), ("2", "shanghai")),
(("3","beijing"), ("3", "shanghai"))
=> (("1","beijing"), ("1", "shanghai"), ("2","beijing"), ("2", "shanghai"), ("3","beijing"), ("3", "shanghai"))

-- Enumerated values (=> union) of replacement partitions tp1, tp2:
(("1","beijing"), ("1", "shanghai")),
(("2","beijing"), ("2", "shanghai"), ("3","beijing"), ("3", "shanghai"))
=> (("1","beijing"), ("1", "shanghai"), ("2","beijing"), ("2", "shanghai"), ("3","beijing"), ("3", "shanghai"))

-- The unions are equal, so tp1 and tp2 can replace p1, p2, and p3.

use_temp_partition_name​

Определяет, какие имена получают основные разделы после замены:

Сценарийuse_temp_partition_name = false (по умолчанию)use_temp_partition_name = true
Число заменяемых разделов = число разделов для заменыСохраняется исходное имя основного раздела (заменяются только данные и свойства)Имя временного раздела становится новым именем основного раздела
Число заменяемых разделов != число разделов для заменыПараметр не влияет на результат; принудительно используется имя временного разделаИспользуется имя временного раздела

Пример 1: замена при равном числе разделов

ALTER TABLE tbl1 REPLACE PARTITION (p1) WITH TEMPORARY PARTITION (tp1);
  • use_temp_partition_name = false (по умолчанию): после замены раздел по-прежнему называется p1, но его данные и свойства берутся из tp1.
  • use_temp_partition_name = true: после замены раздел переименовывается в tp1, а p1 больше не существует.

Пример 2: замена при разном числе разделов

ALTER TABLE tbl1 REPLACE PARTITION (p1, p2) WITH TEMPORARY PARTITION (tp1);
  • Поскольку число заменяемых разделов (2) не равно числу разделов для замены (1), use_temp_partition_name не влияет на результат.
  • После замены раздел называется tp1, а исходные разделы p1 и p2 больше не существуют.
Примечания о замене

После успешной замены заменённые основные разделы удаляются без возможности восстановления. Перед заменой всегда проверяйте корректность данных во временных разделах.

Удаление временного раздела​

Чтобы удалить временные разделы, которые больше не нужны, используйте ALTER TABLE DROP TEMPORARY PARTITION:

ALTER TABLE tbl1 DROP TEMPORARY PARTITION tp1;

Примечание: после удаления временного раздела его нельзя восстановить с помощью команды RECOVER.


Взаимодействие с другими операциями​

Операции DROP​

ОперацияВлияние на временные разделыВозможность восстановления
DROP DATABASE / DROP TABLEВременные разделы базы данных или таблицы удаляются вместе с нейСаму базу данных или таблицу можно восстановить с помощью RECOVER в течение срока хранения, но временные разделы не восстанавливаются
ALTER ... DROP PARTITION (основной раздел)Не влияет на временные разделыОсновной раздел можно восстановить с помощью RECOVER в течение срока хранения
ALTER ... DROP TEMPORARY PARTITIONУдаляет указанный временный разделВосстановление невозможно

Операции TRUNCATE​

ОперацияРезультат
TRUNCATE TABLEВременные разделы таблицы удаляются без возможности восстановления
TRUNCATE TABLE ... PARTITION (очистка основного раздела)Не влияет на временные разделы
Выполнение TRUNCATE для временного разделаНе поддерживается

Операции ALTER​

  • Пока в таблице есть временные разделы, нельзя выполнять изменение схемы, операции rollup и другие подобные изменения.
  • Пока в таблице выполняется операция изменения, добавлять временные разделы нельзя.

Часто задаваемые вопросы​

Вопрос 1: Обращаются ли обычные запросы SELECT к временным разделам?

Нет. Доступ к временному разделу можно получить только явно, с помощью конструкции TEMPORARY PARTITION(...). Обычные запросы, отчёты и представления не читают данные из временных разделов.

Вопрос 2: Должны ли число реплик и число бакетов временного раздела совпадать с соответствующими значениями основных разделов?

Нет. В этом состоит одно из главных преимуществ временных разделов: для нового раздела можно задать другие значения replication_num и BUCKETS, а затем выполнить атомарное переключение с помощью REPLACE PARTITION.

Вопрос 3: Как перезаписать данные раздела без перерывов в их доступности?

Выполните действия в следующем порядке:

  1. Выполните ALTER TABLE ... ADD TEMPORARY PARTITION, чтобы создать временный раздел.
  2. Используйте INSERT INTO или задание загрузки, чтобы записать новые данные во временный раздел.
  3. Проверьте корректность данных во временном разделе.
  4. Выполните ALTER TABLE ... REPLACE PARTITION ... WITH TEMPORARY PARTITION ... для атомарной замены.

На протяжении всего процесса основной раздел остаётся доступным для чтения внешними запросами.

Вопрос 4: Что делать, если замена завершилась ошибкой или данные некорректны?

До замены данные остаются во временном разделе, а основной раздел не затрагивается. Если вы обнаружили проблему с данными, выполните ALTER TABLE ... DROP TEMPORARY PARTITION, чтобы удалить временный раздел, и загрузите данные заново. После успешной замены исходные данные основного раздела восстановить нельзя.

Вопрос 5: Можно ли одновременно добавить несколько временных разделов в одну таблицу?

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

Распространённые ошибки​

Ошибка / признакВозможная причинаРешение
Не удалось добавить временный раздел: раздел уже существуетИмя совпадает с именем существующего основного или временного разделаИзмените имя временного раздела
Не удалось добавить временный раздел: пересечение диапазоновДиапазон или перечисляемые значения пересекаются с существующим временным разделомИзмените диапазон или сначала удалите конфликтующий временный раздел
Не удалось выполнить замену: проверка strict_range не пройденаОбъединения диапазонов разделов Range не совпадаютУбедитесь, что объединения совпадают, или явно задайте strict_range = false
Не удалось выполнить замену: перечисляемые значения разделов List не совпадаютДля разделов List параметр strict_range всегда имеет значение trueИзмените временные разделы так, чтобы объединение их перечисляемых значений в точности совпадало с объединением значений основных разделов
Невозможно выполнить изменение схемыВ таблице есть временные разделыСначала удалите или замените все временные разделы
Временный раздел удалён по ошибкеRECOVER не поддерживает восстановление временных разделовСоздайте раздел заново и повторно загрузите данные