Перейти к содержанию
Learning Platform
Глоссарий Troubleshooting
Урок 11.05 · 30 мин
Продвинутый
DELETElightweightmaskmutationsprojections

Lightweight DELETE

ClickHouse 25.3 ввёл стандартный SQL-синтаксис DELETE FROM table WHERE expr — mask-based механизм удаления, который работает принципиально иначе, чем тяжёлые мутации ALTER TABLE DELETE. Понимание этой разницы критично для выбора правильного подхода к удалению данных.


Механизм: маски удаления

Когда вы выполняете DELETE FROM, ClickHouse не перезаписывает данные немедленно. Вместо этого применяется маска удаления:

  1. Для каждой части (part) создаётся bitmap-маска с отметкой удалённых строк
  2. Маска применяется немедленно ко всем SELECT — строки исчезают из результатов
  3. Физическая очистка происходит при следующем merge-цикле
-- Стандартный SQL DELETE (ClickHouse 25.3+, доступен в 26.3 LTS)
DELETE FROM events WHERE toDate(event_time) < '2024-01-01';

-- Строки немедленно исчезают из SELECT:
SELECT count() FROM events WHERE toDate(event_time) < '2024-01-01';
-- Результат: 0 (маска применена)

Принудительное физическое удаление (без ожидания merge):

-- Принудительная физическая очистка замаскированных строк
ALTER TABLE events APPLY DELETED MASK;
Жизненный цикл Lightweight DELETE
DELETE FROM … WHERE exprDELETE FROM: стандартный SQL-синтаксис. ClickHouse разбирает WHERE-условие и определяет какие строки попадают под удаление. Операция O(parts) — обходит только части, не строки.
мгновенно
Маска применена к SELECTМаска удаления (deletion mask): bitmap, где 1 = строка удалена. Создаётся для каждого part, затронутого WHERE-условием. SELECT автоматически фильтрует строки по маске — они невидимы немедленно.
при следующем merge
Физическое удаление при mergeФизическая очистка при merge: когда ClickHouse объединяет части, замаскированные строки не попадают в результирующую часть. Дисковое пространство освобождается только на этом этапе.
опционально: немедленно
ALTER TABLE … APPLY DELETED MASKAPPLY DELETED MASK: принудительная физическая очистка без ожидания merge. Полезно для GDPR-compliance, когда нужно гарантировать немедленное уничтожение данных на диске.

Производительность: O(parts), не O(rows)

Сложность lightweight DELETE определяется числом частей (parts), а не числом строк — это принципиальное отличие от тяжёлых мутаций:

ОперацияСложностьСинхронностьМеханизм
DELETE FROM (lightweight)O(parts)Синхронная (маска)Bitmap-маска на part
ALTER TABLE DELETE (mutation)O(rows × cols)АсинхроннаяПолная перезапись колонок
DROP PARTITIONO(1)СинхроннаяПереименование директории

Для таблицы с 10 миллиардами строк в 1000 частях:

  • DELETE FROM — обходит 1000 частей для создания масок (~секунды)
  • ALTER TABLE DELETE — перезаписывает все колонки во всех строках (~часы)

Ограничение: несовместимость с projections

WARNING

Lightweight DELETE несовместим с таблицами, содержащими projections. Попытка выполнить DELETE FROM на такой таблице завершится ошибкой.

Причина: mask-based механизм не обновляет projection parts — они остаются с устаревшими данными. ClickHouse отклоняет операцию для защиты консистентности.

Решение для таблиц с projections: используйте тяжёлую мутацию ALTER TABLE t DELETE WHERE ....

-- Таблица с projection:
CREATE TABLE events_with_proj (
    user_id UInt64,
    event_time DateTime,
    event_type String
) ENGINE = MergeTree
ORDER BY (user_id, event_time);

ALTER TABLE events_with_proj ADD PROJECTION user_summary (
    SELECT user_id, count() GROUP BY user_id
);

-- ЭТО ЗАВЕРШИТСЯ ОШИБКОЙ:
-- DELETE FROM events_with_proj WHERE user_id = 42;
-- Error: Lightweight delete is not supported for tables with projections

-- Правильный подход для таблиц с projections:
ALTER TABLE events_with_proj DELETE WHERE user_id = 42;

Когда использовать Lightweight DELETE

Lightweight DELETE оптимален в следующих сценариях:

  • GDPR/право на забвение: удаление данных конкретного пользователя (< 10% строк таблицы)
  • Точечная коррекция: удаление некорректных записей после загрузки
  • Таблицы без проекций: если нет ALTER TABLE ... ADD PROJECTION
  • Требование немедленной видимости: маска применяется синхронно, данные исчезают сразу

Не используйте Lightweight DELETE если:

  • Таблица содержит projections → ALTER TABLE DELETE
  • Нужно удалить > 10% строк → рассмотрите DROP PARTITION
  • Требуется точечное освобождение диска без ожидания merge → APPLY DELETED MASK или ALTER TABLE DELETE
-- Проверка наличия projections в таблице:
SELECT name, type FROM system.projections WHERE table = 'events';

-- Мониторинг замаскированных строк (до физической очистки):
SELECT
    table,
    sum(rows) AS total_rows,
    sum(data_compressed_bytes) AS compressed_size
FROM system.parts
WHERE table = 'events' AND active
GROUP BY table;

Ключевые выводы

  1. DELETE FROM (25.3+) создаёт bitmap-маску: строки исчезают из SELECT немедленно, физическая очистка при merge.
  2. Сложность O(parts) — принципиально быстрее мутаций O(rows × cols) для точечных удалений.
  3. ALTER TABLE t APPLY DELETED MASK принудительно очищает диск без ожидания merge.
  4. Lightweight DELETE несовместим с таблицами, содержащими projections — для них используйте ALTER TABLE t DELETE WHERE ....
  5. Иерархия производительности: DROP PARTITION >> DELETE FROM (lightweight) >> ALTER TABLE DELETE (mutation).
xmin/xmax: версии строк и маркировка удалений в PostgreSQL Шесть измерений data quality

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 8