backfilldata engineeringsqlairflowидемпотентностьсобеседование

Бэкфилл данных: что это, идемпотентность, SQL/Airflow

2026-06-07 9 мин

Бэкфилл данных (backfill) — это перезаливка или пересчёт исторических данных за прошлые периоды, когда логики раньше не существовало, она была сломана или вы добавили новый источник. Главное правило: бэкфилл должен быть идемпотентным — повторный запуск за тот же период не создаёт дублей и не меняет итог. Достигается это удалением партиции перед вставкой (delete-insert), либо MERGE/UPSERT по ключу. Если этого нет — вы получите задвоенную выручку и расхождение с продакшеном.

На собесе аналитика данных вопрос про бэкфилл — индикатор зрелости. Junior отвечает «ну, перезальём данные», Middle уточняет про идемпотентность и дедупликацию. Разберём так, чтобы вы попали во вторую категорию.

Что такое бэкфилл данных простыми словами?

Представьте: вы три месяца считали витрину заказов, а потом обнаружили баг — не учитывались возвраты. Исправить логику на будущее мало: исторические цифры за три месяца неверны. Нужно пересчитать прошлое по новой логике — это и есть бэкфилл.

Типичные триггеры бэкфилла:

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

Чем бэкфилл отличается от реплея и инкремента?

Термины часто путают. Держите различия в голове:

ПонятиеЧто делаетКогда
ИнкрементГрузит только новые данные (последний день)Ежедневно по расписанию
БэкфиллПересчитывает прошлые периоды по текущей логикеПосле фикса бага / новой колонки
Реплей (replay)Прогоняет события заново из лога/очередиВосстановление после сбоя стрима
Full refreshУдаляет всё и строит витрину с нуляРадикальная смена модели

Бэкфилл — это почти всегда «частичный full refresh» по конкретному диапазону дат. Поэтому ключевой навык — уметь ограничить пересчёт нужными партициями и не задеть остальное.

Что такое идемпотентность и зачем она нужна?

Идемпотентность — свойство операции давать один и тот же результат при любом числе повторов. Если запустить бэкфилл за 2026-01-15 один раз или пять раз подряд, в таблице должна быть одна версия данных за эту дату, а не пять.

Почему это критично: бэкфиллы падают на середине, их перезапускают, Airflow ретраит таски автоматически. Если ваш INSERT просто добавляет строки, каждый ретрай удваивает данные. Идемпотентность — это страховка от человеческого фактора и от инфраструктуры.

Три рабочих паттерна идемпотентного бэкфилла:

Как сделать бэкфилл в SQL без дублей?

Базовый delete-insert внутри одной транзакции выглядит так: сначала чистим целевой день, затем вставляем пересчитанный результат.

DELETE FROM mart.orders_daily WHERE event_date = '2026-01-15'; INSERT INTO mart.orders_daily SELECT event_date, SUM(amount) FROM raw.orders WHERE event_date = '2026-01-15' GROUP BY event_date;

Оберните оба запроса в транзакцию (BEGIN ... COMMIT), чтобы при падении INSERT не остаться с пустой партицией.

Если в источнике сами по себе встречаются дубли событий, добавьте дедупликацию через оконную функцию — оставляете одну строку на бизнес-ключ:

WITH ranked AS (SELECT *, ROW_NUMBER() OVER (PARTITION BY order_id ORDER BY updated_at DESC) AS rn FROM raw.orders WHERE event_date = '2026-01-15') SELECT * FROM ranked WHERE rn = 1

Альтернатива delete-insert — MERGE (или INSERT ... ON CONFLICT DO UPDATE в PostgreSQL). MERGE предпочтителен, когда нужно частично обновить существующие строки, а не выкидывать всю партицию. Эти конструкции — частая практика на тренажёре: отработать ROW_NUMBER, ON CONFLICT и оконные функции можно в SQL-тренажёре с автопроверкой.

Для ClickHouse идиома другая — INSERT INTO ... SELECT с предварительным ALTER TABLE ... DROP PARTITION, потому что обычный DELETE там тяжёлый (мутация). Замена партиции целиком атомарна и идемпотентна.

Как организовать бэкфилл в Airflow?

В Airflow бэкфилл — это запуск DAG за прошлые execution_date. Ключевые принципы:

Главная ошибка новичков — захардкодить CURRENT_DATE в SQL. Тогда бэкфилл за январь перезапишет январские партиции… сегодняшними данными. Всегда подставляйте дату из контекста выполнения.

Какие типичные ошибки убивают бэкфилл?

Чек-лист перед запуском бэкфилла: операция идемпотентна → дата параллелизуется → задан диапазон → ограничен параллелизм → есть бэкап или способ откатиться → продуманы зависимые downstream-витрины.

Как проверить, что бэкфилл прошёл корректно?

После прогона обязательно сверьтесь:

Где потренироваться?

Бэкфилл проверяют на собесах через SQL-задачи (дедупликация, оконные функции, идемпотентный пересчёт) и через системные вопросы по ETL. Прокачать оба слоя:

Связка простая: понимаете идемпотентность концептуально, умеете руками написать delete-insert и дедуп через ROW_NUMBER, знаете подводные камни Airflow — и вопрос про бэкфилл на собесе перестаёт быть страшным. Начните с тренажёра, там это закрепляется быстрее всего.

Потренируй SQL для бэкфилла на реальных задачах
Идемпотентный пересчёт, дедупликация через ROW_NUMBER, MERGE и оконные функции — всё это спрашивают на собесах. Прокачай навык в браузерном тренажёре с автопроверкой.
Открыть SQL-тренажёр →