Logical date (tên cũ execution_date) là mốc thời gian mà một DAG run đại diện, còn data interval là khoảng dữ liệu run đó phụ trách. Cách Airflow tính hai mốc này đổi giữa Airflow 2 và 3, và đây là chỗ hay bị hỏi.
DAG @daily, run lúc 00:00 ngày 25/9 | Airflow 2 (mặc định) | Airflow 3 (mặc định) |
|---|---|---|
| Timetable | CronDataIntervalTimetable | CronTriggerTimetable |
| Data interval | 24/9 00:00 → 25/9 00:00 | 25/9 00:00 → 25/9 00:00 (bằng nhau) |
| Logical date | 24/9 (đầu khoảng) | 25/9 (lúc trigger) |
Ở Airflow 2, run của ngày 24/9 chỉ chạy sau khi ngày 24/9 kết thúc, nên người mới hay tưởng DAG chạy trễ một ngày. Airflow 3 đặt [scheduler] create_cron_data_intervals = False để logical date khớp với lúc chạy, đổi lại data interval có độ dài bằng 0. Pipeline cần xử lý trọn "ngày hôm qua" thì khai báo timetable rõ ràng rồi lọc theo khoảng, không dùng now():
from airflow.sdk import dag, CronDataIntervalTimetable
@dag(schedule=CronDataIntervalTimetable("0 0 * * *", timezone="Asia/Ho_Chi_Minh"), ...)SELECT * FROM orders
WHERE created_at >= '{{ data_interval_start }}'
AND created_at < '{{ data_interval_end }}';Như vậy run của ngày 24/9 luôn xử lý đúng ngày 24/9, dù chạy hôm nay hay chạy lại tuần sau.
- Catchup:
catchup=Truethì khi bật DAG, scheduler tạo run cho mọi khoảng bị lỡ kể từstart_date. Airflow 3 mặc định làFalse, tránh cảnh bật DAG cóstart_datetừ năm ngoái rồi nó chạy liền 365 run. - Retries:
retriesvàretry_delay, thường đặt trongdefault_args. Task lỗi chuyển sangup_for_retryrồi chạy lại — hợp với lỗi tạm thời như mất kết nối, không cứu được lỗi logic. - Backfill: chạy lại một dải ngày cũ khi sửa bug hoặc thêm bảng mới. Ở Airflow 3 dùng
airflow backfill create --dag-id daily_sales --from-date 2026-09-01 --to-date 2026-09-07hoặc tạo từ UI (Airflow 2 làairflow dags backfill); chỉ cần chạy lại vài task thì dùng Clear trên task instance.
Lưu ý: nâng DAG từ Airflow 2 lên 3 mà vẫn lọc theo data_interval_start/data_interval_end với schedule cron trần thì khoảng lọc rỗng, job chạy xanh nhưng không nạp dòng nào. Ngoài ra, retry và backfill chỉ an toàn khi task idempotent: chạy lại một khoảng thì ghi đè đúng khoảng đó, không nhân đôi dữ liệu.