dbt

Средний уровень

Инкрементальные модели dbt: когда «incremental» тихо превращается в full refresh

Весь смысл инкрементальной модели — обрабатывать только новые или изменённые строки. Несколько распространённых триггеров незаметно превращают это в полную пересборку при каждом запуске, без единой ошибки.

Читать на:
Изменение схемы Забытый флаг --full-refresh Удалённая целевая таблица
Частые причины непреднамеренной полной пересборки, примерно по частоте — иллюстративно, не измерено.

dbt решает, выполнять модель инкрементально или как полную пересборку, на основе нескольких условий — и не одно из них может незаметно измениться уже после месяцев стабильной работы модели.

Как dbt выбирает между incremental и full refresh

Помимо явного флага --full-refresh, dbt переходит на полную пересборку, если целевой таблицы ещё не существует, или — в зависимости от настройки on_schema_change — если набор колонок модели изменился с момента создания таблицы. on_schema_change: "fail" сразу останавливает запуск при несовпадении; "ignore" (значение по умолчанию) или неверно настроенный "append_new_columns"/"sync_all_columns" могут вместо этого тихо вызвать полную пересборку в зависимости от того, что реально изменилось.

Почему это незаметно: без ошибки, просто гораздо более долгий запуск

С точки зрения dbt full refresh — не состояние отказа: запуск всё равно показывает «зелёный» статус. Меняется execution_time в run_results.json, резко выходящий за обычный диапазон, и строка в счёте за хранилище, не соответствующая тому, что «мы добавили данные всего за один день». Никого не будят из-за медленного успеха.

Как заметить это раньше, чем счёт

Сравнивайте execution_time каждой инкрементальной модели с её собственным скользящим средним, а не с фиксированным порогом — модель, обычно занимающая 40 секунд, а теперь занявшая 25 минут, и есть сигнал, независимо от того, что считается «приемлемым» для другой модели в том же проекте.

Модель, с которой это произошло, не сломана — её конфигурация просто делает ровно то, что вы ей сказали, при условии, которое вы не ожидали встретить. Фикс почти всегда в on_schema_change или в том, что изменило набор колонок выше по пайплайну, а не в SQL самой модели.

Посмотрите, как это выглядит на вашем собственном пайплайне.

Загрузите реальный event log Spark, run_results.json от dbt или экспорт метрик Flink — и получите конкретные рекомендации, которые нужно одобрить, а не ещё одно эмпирическое правило.