Пакетное удаление при загрузке
Пакетное удаление при загрузке представляет собой способ удаления, доступный в модели Unique Key в Doris. При загрузке данных передаётся столбец с маркерами удаления, с помощью которого нужные строки помечаются как удалённые, а фоновый процесс Compaction асинхронно очищает их.
По сравнению с оператором DELETE маркеры удаления обеспечивают более высокую производительность и удобство при пакетном удалении и в сценариях CDC.
Сценарии применения
| Сценарий | Описание |
|---|---|
| Синхронизация CDC | При синхронизации базы данных OLTP (например, MySQL) с Doris через binlog в журнале чередуются операции Insert и Delete. Маркеры удаления позволяют единообразно обрабатывать оба типа операций, упрощая код и повышая производительность загрузки и запросов. |
| Пакетное удаление по первичному ключу | Если требуется удалить большой объём данных по первичному ключу, каждый оператор DELETE создаёт пустой Rowset и новую версию данных. Частые удаления существенно снижают производительность запросов. Маркеры удаления можно записывать пакетами, что позволяет избежать этой проблемы. |
Сравнение с оператором DELETE
| Критерий | Пакетное удаление при загрузке | Оператор DELETE |
|---|---|---|
| Поддерживаемая модель | Unique Key | Unique Key / Aggregate Key / Duplicate Key |
| Способ запуска | Передача маркеров удаления при загрузке | Выполнение SQL |
| Версия данных | Использует ту же версию, что и загрузка | При каждом выполнении создаёт новую версию |
| Производительность удаления больших пакетов | Высокая | Низкая |
| Применение в сценариях CDC | Встроенная поддержка | Требует дополнительной обработки |
Принцип работы
Основной механизм
- Скрытый столбец: каждая таблица Unique Key содержит скрытый столбец
__DORIS_DELETE_SIGN__. Значение1означает, что строка помечена как удалённая. - Запись при загрузке: в задании загрузки можно указать, какие строки следует пометить как удалённые, с помощью условий сопоставления. Синтаксис немного различается в зависимости от способа загрузки.
- Фильтрация при запросах: при планировании запроса FE автоматически добавляет условие фильтрации
__DORIS_DELETE_SIGN__ != true, поэтому помеченные строки не видны пользователям. - Фоновая очистка: процесс Compaction на BE периодически физически удаляет строки, помеченные как удалённые.
Пример с данными
Шаг 1: Создание таблицы
Создайте таблицу Unique Key:
CREATE TABLE example_table (
id BIGINT NOT NULL,
value STRING
)
UNIQUE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 10
PROPERTIES (
"replication_num" = "3"
);
Шаг 2: Просмотр скрытых столбцов
Используйте переменную сеанса show_hidden_columns, чтобы отобразить скрытые столбцы:
mysql> set show_hidden_columns=true;
mysql> desc example_table;
+-----------------------+---------+------+-------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+---------+------+-------+---------+-------+
| id | bigint | No | true | NULL | |
| value | text | Yes | false | NULL | NONE |
| __DORIS_DELETE_SIGN__ | tinyint | No | false | 0 | NONE |
| __DORIS_VERSION_COL__ | bigint | No | false | 0 | NONE |
+-----------------------+---------+------+-------+---------+-------+
Шаг 3: Запись маркера удаления
Предположим, что таблица содержит следующие данные:
+------+-------+
| id | value |
+------+-------+
| 1 | foo |
| 2 | bar |
+------+-------+
Используйте INSERT INTO, чтобы записать маркер удаления для строки, где id = 1 (это лишь иллюстрация; в рабочей среде используйте соответствующий способ загрузки):
mysql> insert into example_table (id, __DORIS_DELETE_SIGN__) values (1, 1);
Шаг 4: Проверка результатов запроса
По умолчанию запросы автоматически отфильтровывают помеченные строки:
mysql> select * from example_table;
+------+-------+
| id | value |
+------+-------+
| 2 | bar |
+------+-------+
После включения show_hidden_columns видно, что строка с id = 1 всё ещё присутствует и лишь помечена как удалённая:
mysql> set show_hidden_columns=true;
mysql> select * from example_table;
+------+-------+-----------------------+-----------------------+
| id | value | __DORIS_DELETE_SIGN__ | __DORIS_VERSION_COL__ |
+------+-------+-----------------------+-----------------------+
| 1 | NULL | 1 | 3 |
| 2 | bar | 0 | 2 |
+------+-------+-----------------------+-----------------------+
Режимы слияния данных при загрузке
Параметр merge_type управляет слиянием данных в задании загрузки. Поддерживаются три режима:
| merge_type | Поведение | Типичное применение |
|---|---|---|
| APPEND (по умолчанию) | Все загружаемые данные добавляются к существующим | Обычная запись данных |
| DELETE | Удаляет все строки, значения столбцов Key которых совпадают с загружаемыми данными | Пакетное удаление по первичному ключу |
| MERGE | Выполняет APPEND или DELETE для каждой строки в зависимости от условия DELETE ON | Сценарии CDC со смешанными операциями Insert/Delete |
Примечание:
MERGEнеобходимо использовать вместе сDELETE ON <condition>.
Синтаксис для каждого способа загрузки
Синтаксис задания маркеров удаления немного различается в зависимости от способа загрузки. Ниже описан каждый из них.
Stream Load
Использование: задайте поля columns, merge_type и delete в заголовке HTTP.
Пример:
-H "columns: k1, k2, label_c3"
-H "merge_type: [MERGE|APPEND|DELETE]"
-H "delete: label_c3=1"
Описание параметров:
columns: сопоставление полей при загрузке. Должно включать столбец с маркером, по которому определяется необходимость удаления.merge_type: режим слияния. Допустимые значения:APPEND,DELETEиMERGE.delete: действует приmerge_type=MERGE. Задаёт условие удаления.
Дополнительные примеры см. в разделах «Указание merge_type для операции Delete» и «Указание merge_type для операции Merge» руководства по Stream Load.
Broker Load
Использование: задайте маркеры удаления в предложении LOAD с помощью ключевого слова [MERGE|APPEND|DELETE] и предложения DELETE ON.
Пример синтаксиса:
LOAD LABEL db1.label1
(
[MERGE|APPEND|DELETE] DATA INFILE("hdfs://abc.com:8888/user/palo/test/ml/file1")
INTO TABLE tbl1
COLUMNS TERMINATED BY ","
(tmp_c1, tmp_c2, label_c3)
SET
(
id = tmp_c2,
name = tmp_c1
)
[DELETE ON label_c3=true]
)
WITH BROKER 'broker'
(
"username" = "user",
"password" = "pass"
)
PROPERTIES
(
"timeout" = "3600"
);
Routine Load
Использование: при создании задания Routine Load задайте маркеры удаления с помощью предложений WITH [MERGE|APPEND|DELETE] и DELETE ON.
Пример синтаксиса:
CREATE ROUTINE LOAD example_db.test1 ON example_tbl
[WITH MERGE|APPEND|DELETE]
COLUMNS(k1, k2, k3, v1, v2, label),
WHERE k1 > 100 and k2 like "%doris%"
[DELETE ON label=true]
PROPERTIES
(
"desired_concurrent_number" = "3",
"max_batch_interval" = "20",
"max_batch_rows" = "300000",
"max_batch_size" = "209715200",
"strict_mode" = "false"
)
FROM KAFKA
(
"kafka_broker_list" = "broker1:9092,broker2:9092,broker3:9092",
"kafka_topic" = "my_topic",
"kafka_partitions" = "0,1,2,3",
"kafka_offsets" = "101,0,0,200"
);
Часто задаваемые вопросы
Вопрос 1: Какие модели таблиц поддерживают пакетное удаление при загрузке?
Поддерживается только модель Unique Key. Для таблиц Aggregate Key и Duplicate Key используйте оператор DELETE.
Вопрос 2: Когда фактически освобождается дисковое пространство, занимаемое данными, помеченными как удалённые?
Данные асинхронно очищаются фоновым процессом Compaction на BE. Сроки зависят от планирования Compaction и количества версий данных; обычно вмешательство пользователя не требуется.
Вопрос 3: Как проверить, помечена ли строка как удалённая?
Выполните SET show_hidden_columns=true;, а затем запросите данные таблицы. Скрытый столбец __DORIS_DELETE_SIGN__ станет видимым. Значение 1 означает, что строка помечена как удалённая.
Вопрос 4: Какой merge_type следует использовать в сценариях CDC?
Рекомендуется использовать MERGE вместе с DELETE ON для задания условия удаления. Это позволяет обрабатывать операции Insert и Delete совместно в рамках одной загрузки.
Вопрос 5: Влияют ли маркеры удаления на производительность запросов?
Обычные запросы автоматически отфильтровывают помеченные строки, поэтому влияние на производительность незначительно. После завершения фонового процесса Compaction помеченные данные физически удаляются.