バックフィルとリプレイの設計
いつ使用するか
- 新しいモデル/パイプラインの履歴をロードする場合。
- 変換バグを修正した後、過去のウィンドウを再処理する場合。
- イベントをリプレイしたり、生データからテーブルを再導出する場合。
- 通常のインクリメンタル実行には使用しないでください(
building-dbt-models/authoring-airflow-dagsを使用してください)。
なぜ注意が必要か
バックフィルはデータエンジニアリングにおける最も危険な定期操作です。履歴を書き換えます。誤った方法で行うと、二重計上、昨日の数値の変更、プロダクションの過負荷を引き起こします。正しく行えば、退屈で反復可能な作業になります。前提条件はべき等性です(writing-idempotent-transformations を参照)。
ワークフロー
- [ ] バックフィル前に変換がべき等であることを確認する(再実行 == 1回の実行)
- [ ] 正確なウィンドウとパーティション粒度を定義する
- [ ] 1つのパーティションでドライランを実行し、カウント/合計をソースと検証する
- [ ] 一度に全てを実行するのではなく、パーティションごとに(バウンド並列性で)実行する
- [ ] バックフィルコンピュートをプロダクションワークロードから分離する
- [ ] 合計を検証して調整し、通常のスケジューリングを再開する
- まずべき等性を証明する。 ウィンドウの再実行で結果が変わる可能性がある場合は、履歴に触れる前にそれを修正してください。非べき等ジョブをバックフィルするとデータが増殖します。
- 範囲を正確に定義する。 正確な開始日/終了日とパーティション単位(日/時間/地域)を指定します。
- 1つのパーティションでドライランを実行し、スケールアウト前にソースと照合します。
- 実行をチャンクに分割する。 監視、一時停止、再開ができるように、パーティションをバウンドバッチで処理します。巨大な単一のバウンドなしジョブは避けてください。
- コンピュートを分離する。 別のウェアハウス/クラスター/プールを使用して、バックフィルがプロダクションのSLAを枯渇させないようにします。
- 検証して再開する。 バックフィル範囲全体の合計を調整し、通常のスケジュールに戻します。
パターン
べき等なパーティションごとのバックフィル — 各パーティションの上書きは独立しており、再試行しても安全です。
# バウンド並列性、1日ずつ処理。各日は自身のパーティションを上書きします。
for day in $(seq_dates 2026-01-01 2026-01-31); do
run_transform --run-date "$day" # その日のみの delete-insert / MERGE
done
Airflow — catchup/backfill はインターバルを再実行します。タスクがべき等でデータインターバルによってパラメータ化されている場合のみ安全です。dbt — インクリメンタルモデルを対象ウィンドウにフィルターするか、バウンドウィンドウで --full-refresh を実行します。
分離とスロットル — 専用のウェアハウス/クラスターと同時実行数の上限を設定し、バックフィルがライブダッシュボードを劣化させないようにします。
よくある落とし穴
- 非べき等ジョブのバックフィル — 重複や合計値の変動を引き起こします。まずべき等にしてください。
- 巨大な単一のバウンドなしジョブ — 監視や再開ができず、プロダクションを過負荷にします。パーティションごとに実行してください。
- プロダクションコンピュートの共有 — バックフィルは負荷を急増させ、SLAを破綻させます。分離してください。
- 検証なし — 成功を前提としないでください。範囲全体のカウント/合計を調整してください。
- バックフィル途中でのロジック変更 — 履歴に不整合が生じます。実行全体でコードバージョンを固定してください。
- ダウンストリームを忘れる — 基本テーブルをバックフィルしても、依存するマート/集計を更新しなければ、それらは不整合のまま残ります。