Обновление и удаление данных
Кратко Apache Doris поддерживает SQL-операторы
UPDATEиDELETE, как транзакционная база данных, а также upsert с частичным обновлением столбцов через потоковую загрузку, массовое удаление по предикату и атомарную замену партиций. В таблицах Unique Key движок Merge-on-Write обеспечивает низкую задержку запросов: удалённые строки помечаются в битовой карте каждого rowset во время записи, поэтому объединять версии при чтении не требуется. Начиная с версии 2.1, Merge-on-Write используется по умолчанию для Unique Key.

Зачем нужны обновление и удаление данных в Apache Doris?
Обновление и удаление данных в Apache Doris позволяют выполнять транзакционные изменения на уровне строк в аналитическом движке, поэтому для CDC, удаления данных по требованиям GDPR и разовых исправлений не приходится переписывать партиции. Большинство аналитических движков создавались исходя из того, что в хранилища данные только добавляются. Затем появились CDC и GDPR, а ещё никуда не делся простой факт: в рабочих данных бывают ошибки. Если ваше хранилище не может исправить одну некорректную строку без перезаписи партиции, каждое запоздавшее исправление превращается в заявку команде эксплуатации.
- Задание Flink CDC отслеживает изменения в MySQL, и каждое обновление строки должно попадать в хранилище за считаные секунды.
- Пользователь запрашивает удаление данных по GDPR. Данные нужно удалить из хранилища, а не отложить их удаление «до следующей компактации».
- Один отчёт показывает неверное число из-за опечатки в единственной строке таблицы фактов на 10 миллиардов строк.
Apache Doris решает все три задачи с помощью полноценных SQL-операторов: UPDATE, DELETE FROM ... WHERE, upsert с частичным обновлением столбцов через Stream Load, а также TRUNCATE или атомарной замены партиций для массовой очистки. Ни один из этих способов не требует, чтобы таблица была маленькой, и ни один не заставляет вас затем планировать задание на перезапись данных.
Что представляют собой обновление и удаление данных в Apache Doris?
Обновление и удаление данных в Apache Doris включают четыре механизма: SQL-оператор UPDATE, DELETE по предикату, upsert с частичным обновлением столбцов и замену партиций. В таблицах Unique Key их работу обеспечивает движок Merge-on-Write. SQL-оператор UPDATE на уровне строк работает в таблицах Unique Key, удаление по предикату через DELETE FROM ... WHERE работает в любых таблицах, upsert с частичным обновлением столбцов выполняется при загрузке данных (с заголовком Stream Load partial_columns: true или соответствующей переменной сеанса), а операции на уровне партиций включают TRUNCATE PARTITION и атомарную замену с использованием временных партиций. В основе модели Unique Key лежит Merge-on-Write (MoW), благодаря которому удаления и обновления вступают в силу при записи, а не при выполнении запросов. MoW появился в версии 1.2 и стал режимом по умолчанию для Unique Key в версии 2.1.
Основные термины
Unique Key model: модель таблицы, в которой для каждого первичного ключа хранится одна строка. Необходима дляUPDATEи пакетных операций upsert.Merge-on-Write (MoW): при записи Apache Doris ищет каждый новый ключ в существующих данных, помечает старую строку в битовой карте удаления и записывает новую строку в новый rowset.Delete bitmap: битовая карта для каждого rowset с идентификаторами строк, которые запросы должны пропускать. Она заменяет объединение версий по каждому ключу при чтении.Partial column update: запись, затрагивающая только часть столбцов. Apache Doris считывает недостающие значения из существующих строк и записывает обратно полную строку.Sequence column(function_column.sequence_col): выбранный пользователем столбец, который указывает MoW, какая версия ключа имеет приоритет, если записи поступают не по порядку.__DORIS_DELETE_SIGN__: скрытый столбец, которому присваивается значение1для логического удаления строки через любой способ загрузки.
Как работают обновление и удаление данных в Apache Doris?
Обновление и удаление данных в Apache Doris выполняются в таблице Unique Key MoW в пять этапов: планирование и чтение, поиск ключей, установка битов удаления для старых строк, запись новых строк в новый rowset и публикация новой версии.
Рассмотрим выполнение UPDATE для таблицы Unique Key MoW:
- Планирование и чтение. FE разбирает оператор, обрабатывает предикат WHERE и направляет чтение к репликам BE. При записи с частичным обновлением столбцов узлы BE дополнительно получают недостающие значения столбцов для каждого затронутого ключа.
- Поиск ключей. Каждый BE обращается к хранящемуся в памяти индексу первичного ключа для каждого rowset, чтобы определить, в каком rowset и под какими идентификаторами строк сейчас находятся затронутые ключи.
- Пометка старых строк. В каждом rowset, содержащем затронутый ключ, в битовой карте удаления устанавливаются биты, соответствующие идентификаторам этих строк. Старые строки остаются на диске, пока их не удалит компактация.
- Запись новых строк. Новые значения вместе с неизменёнными столбцами, которые Apache Doris пришлось прочитать для частичного обновления, записываются в новый rowset со следующим номером версии.
- Публикация. Транзакция фиксируется, новая версия становится видимой, и с этого момента запросы фильтруют строки с помощью объединённой битовой карты удаления. Место, занятое старыми данными, освобождается при компактации.
DELETE FROM ... WHERE выполняется по той же схеме, но без этапа записи. В таблицах Aggregate или Duplicate Apache Doris вместо этого сохраняет предикат в метаданных tablet, а запросы применяют его при чтении.
Быстрый старт
CREATE TABLE orders (
order_id BIGINT,
status VARCHAR(20),
amount DECIMAL(10, 2),
updated DATETIME
)
UNIQUE KEY(order_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 4
PROPERTIES ("function_column.sequence_col" = "updated");
INSERT INTO orders VALUES
(1, 'created', 99.50, '2026-05-08 10:00:00'),
(2, 'created', 149.00, '2026-05-08 10:01:00');
UPDATE orders SET status = 'shipped', updated = NOW() WHERE order_id = 1;
DELETE FROM orders WHERE order_id = 2;
Ожидаемый результат
+----------+---------+--------+---------------------+
| order_id | status | amount | updated |
+----------+---------+--------+---------------------+
| 1 | shipped | 99.50 | 2026-05-08 11:42:31 |
+----------+---------+--------+---------------------+
Заказ 1 перезаписан на месте; заказ 2 удалён. Свойство function_column.sequence_col защищает таблицу от записей, поступающих не по порядку: событие CDC с более ранней временной меткой updated уступит уже существующей строке, даже если поступит после более новой записи.
Когда стоит использовать обновление и удаление данных в Apache Doris?
Обновление и удаление данных в Apache Doris подходят для upsert из CDC в таблицы Unique Key, обновления часто меняющихся столбцов в широких таблицах, удаления отдельных строк по требованиям GDPR, атомарной замены партиций при дозагрузке исторических данных и сборки широких таблиц из нескольких потоков. Эти механизмы не подходят для UPDATE в таблицах Aggregate или Duplicate, обновления отдельных строк в тесном цикле, изменения первичных ключей или массовых операций DELETE по предикату, с которыми можно справиться одной заменой партиции.
Подходящие сценарии
- Конвейеры CDC на Flink и Spark, выполняющие upsert в таблицу Unique Key, где первичный ключ источника используется как ключ Apache Doris.
- Обновление часто меняющихся столбцов в широких таблицах (статус заказа, время последнего появления, текущий баланс) через Stream Load с частичным обновлением столбцов.
- Удаление отдельных строк по идентификатору пользователя в соответствии с GDPR, в том числе в таблицах Duplicate, куда данные только добавляются.
- Дозагрузка исторических данных с атомарной подстановкой исправленной партиции через
ALTER TABLE ... REPLACE PARTITION. - Сборка широких таблиц из нескольких потоков, когда каждый источник отвечает за группу столбцов и записывает только свои столбцы.
Неподходящие сценарии
UPDATEв таблицах Aggregate или Duplicate. Оператор будет отклонён. Повторно загрузите данные через механизм загрузки (в Aggregate для перезаписи значений используетсяREPLACE_IF_NOT_NULL) или смените модель таблицы.- Частые операции
UPDATEдля отдельных строк в тесном цикле. Каждый оператор выполняется в собственной транзакции, и накладные расходы на фиксацию становятся определяющими. Вместо этого выполняйте пакетные обновления через Stream Load сpartial_columns: trueили используйте Group Commit. - Изменение первичного ключа. Механизма перезаписи ключа нет; выполните логическое удаление старой строки через
__DORIS_DELETE_SIGN__и вставьте новую, желательно в рамках одной загрузки. DELETEпо предикату, которому соответствуют многие миллиарды строк. Каждое удаление сохраняет предикат или битовую карту, которые затем приходится обрабатывать при компактации; замена партиции илиINSERT OVERWRITEвыполняется быстрее.DELETEв модели Aggregate по неключевым столбцам. Предикат должен фильтровать только по ключевым столбцам: движок не может проверять условия по столбцам значений до агрегации.
Дополнительные материалы
- Обзор обновления и удаления данных
- Обзор обновления: SQL UPDATE, частичное обновление столбцов, столбец последовательности
- Частичное обновление столбцов
- Обзор удаления: удаление по предикату, пакетное удаление, атомарная замена
- Модель данных: почему именно модель таблиц Unique Key обеспечивает работу UPDATE/DELETE и для каких задач подходят Duplicate и Aggregate.
- Точечные запросы с высокой степенью параллелизма: сокращённый путь выполнения, доступный в таблицах Unique Key Merge-on-Write для чтения по схеме KV.
- Changelog / Table Stream: как зафиксированные изменения на уровне строк становятся доступны потребителям данных.
- Apache Doris 2.1.0: Merge-on-Write становится режимом по умолчанию для Unique Key
- Unique Key: модель таблиц, обеспечивающая работу SQL UPDATE/DELETE; Merge-on-Write обрабатывает каждую операцию upsert во время записи.