Airflow backfill и catchup на собеседовании Data Engineer
Карьерник — Duolingo для аналитиков: 10 минут в день тренируй SQL, Python, A/B, статистику, метрики и ещё 3 темы собеса. 1500+ вопросов в Telegram-боте. Бесплатно.
Содержание:
Зачем спрашивают на собесе DE
Backfill — стандартная операция при изменении логики или восстановлении после сбоя. На собесе DE: «как backfill за неделю», «что такое catchup», «depends_on_past». Senior — нюансы intervals.
Catchup
Когда DAG активирован после start_date — Airflow создаёт DAG runs за все пропущенные интервалы.
@dag(
start_date=datetime(2026, 1, 1),
schedule="@daily",
catchup=True # default
)Если активирован 2026-05-01 → создаст 121 DAG runs (за каждый день).
Catchup = False. Только run с текущей даты.
catchup=FalseЧасто полезно — не хочешь, чтобы DAG исторически отрабатывал при первом запуске.
Backfill вручную
CLI:
airflow dags backfill -s 2026-04-01 -e 2026-04-30 my_dagЗапустит DAG runs за каждый день апреля.
Опции:
--reset-dagruns— сбросить existing runs.--rerun-failed-tasks— только failed.--ignore-dependencies— пропустить upstream checks.
depends_on_past
Параметр task. Если True → task ждёт, чтобы тот же task в предыдущем run завершился успешно.
my_task = PythonOperator(
task_id='aggregate',
python_callable=...,
depends_on_past=True
)Когда нужно:
- Stateful pipeline (например, накопительные счётчики).
- Tasks, которые не идемпотентны параллельно.
Минус. Один failed run останавливает всю backfill цепь.
wait_for_downstream — ждать, пока ВСЕ downstream предыдущего run завершатся.
Идемпотентность
Backfill подразумевает: повторный запуск того же DAG run не сломает данные.
Bad: INSERT новых строк → backfill дублирует.
Good:
- DELETE / TRUNCATE партицию + INSERT.
- MERGE / UPSERT.
- INSERT OVERWRITE PARTITION.
Партиция = data_interval_start (день, час).
def aggregate(**context):
ds = context["data_interval_start"].strftime("%Y-%m-%d")
cur.execute(f"DELETE FROM agg WHERE date = '{ds}'")
cur.execute(f"INSERT INTO agg ... WHERE date = '{ds}'")data_interval_start / end
Airflow 2.2+ — переименовано из execution_date.
- data_interval_start. Начало данных, которые task должен обработать.
- data_interval_end. Конец интервала.
- logical_date. Старый
execution_date, для совместимости.
Для daily DAG, run от 2026-05-07 00:00:
- data_interval_start =
2026-05-07 00:00 - data_interval_end =
2026-05-08 00:00 - runs реально в начале
2026-05-08 00:00
То есть DAG обрабатывает «прошедший» интервал.
Частые ошибки
Catchup=True для DAG с большим start_date. Создаёт сотни runs одновременно — ненужная нагрузка. catchup=False для новых DAGs.
Не идемпотентный INSERT. Backfill портит данные.
Игнорировать depends_on_past. Если pipeline stateful — без него backfill пропускает зависимости.
Backfill всего DAG при изменении одной task. Запускай только нужную task через --task-regex.
Полагаться на execution_date для данных. Используй data_interval_start / end — они однозначнее.
Связанные темы
- Airflow на собесе DE
- Airflow Sensors на собесе DE
- Airflow XCom для DE
- Идемпотентность пайплайна для DE
- Подготовка к собесу Data Engineer
FAQ
Что такое max_active_runs?
Лимит одновременных DAG runs. По умолчанию 16. Backfill big — упирается, серилизуется.
Можно backfill в production без downtime?
Да, если идемпотентно. Иначе блокировка / overwrite — нужен maintenance window.
Это официальная информация?
Нет. Статья основана на документации Airflow 2.7+.
Тренируйте Data Engineering — откройте тренажёр с 1500+ вопросами для собесов.