Временный раздел
Временный раздел — это тип раздела в таблице Doris с разделами, независимый от основных разделов. Обычные запросы к нему не обращаются: доступ к нему необходимо явно указывать с помощью специального синтаксиса. Временные разделы используются главным образом для атомарного переключения данных и изменения структуры разделов без влияния на текущие операции чтения и записи.
Сценарии использования
| Сценарий | Описание | Ключевая возможность |
|---|---|---|
| Атомарная перезапись | Перезапись данных раздела без промежутка между удалением старых данных и загрузкой новых | Атомарная замена с помощью REPLACE PARTITION |
| Изменение числа бакетов | Текущее число бакетов существующего раздела неоптимально и требует изменения | Задание нового числа бакетов для временного раздела с последующей заменой |
| Объединение / разбиение разделов | Изменение размера разделов путём объединения нескольких разделов в один или разбиения одного большого раздела на несколько | Перераспределение данных с помощью INSERT INTO с последующей заменой |
Совет: об атомарной перезаписи таблицы без разделов см. в документации по Replace Table.
Основные ограничения
Временный раздел имеет ту же схему таблицы, что и основной раздел, но независим от него в следующих отношениях:
- Столбцы разбиения временного раздела совпадают со столбцами разбиения основных разделов и не могут быть изменены.
- Диапазоны всех временных разделов не должны пересекаться друг с другом.
- Диапазоны временного раздела и основного раздела могут пересекаться.
- Имя временного раздела не может совпадать с именем любого основного или другого временного раздела.
Обзор порядка действий
Типичный процесс состоит из следующих четырёх шагов:
- Добавьте временный раздел (укажите диапазон / перечисляемые значения / число бакетов)
- Загрузите данные во временный раздел (
INSERT INTO/ Stream Load / Broker Load / Routine Load) - Замените основной раздел (
REPLACE PARTITION, атомарная операция) - (Необязательно) Удалите неиспользуемые временные разделы
Добавление временного раздела
Для создания временного раздела используйте оператор 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_range | true | Определяет, насколько строго должны совпадать диапазоны / перечисляемые значения разделов до и после замены (см. ниже) |
use_temp_partition_name | false | Определяет имена основных разделов после замены |
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: Как перезаписать данные раздела без перерывов в их доступности?
Выполните действия в следующем порядке:
- Выполните
ALTER TABLE ... ADD TEMPORARY PARTITION, чтобы создать временный раздел. - Используйте
INSERT INTOили задание загрузки, чтобы записать новые данные во временный раздел. - Проверьте корректность данных во временном разделе.
- Выполните
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 не поддерживает восстановление временных разделов | Создайте раздел заново и повторно загрузите данные |