Queries icon
OutputValues icon
Log icon
If icon
UploadFiles icon
Set icon
Fail icon
Schedule icon

Out-of-Order CDC Log Compaction and Point-in-Time Merger with DuckDB

Compact out-of-order CDC changelogs with LSN Last-Write-Wins, purge tombstones, and enrich point-in-time FX rates in DuckDB with invariant gating.

Categories
Data

Change Data Capture (CDC) streams from operational databases often suffer from out-of-order arrivals, duplicate replays, and uncompacted delete tombstones.

This blueprint implements an in-engine CDC log compaction pipeline using embedded DuckDB. It resolves mutations via WAL Log Sequence Numbers (LSN), purges deleted records, enriches transactions with temporal exchange rates via DuckDB ASOF LEFT JOIN, and gates publication on row-conservation and content-integrity checks before publishing to Namespace Files and the KV store.

How it works

  1. Demo Staging: When input URIs are empty, stage_demo_datasets generates baseline orders, exchange rates, and a CDC changelog with duplicate IDs, clock-skewed commits, and delete tombstones.
  2. Two-Tier CDC Compaction: compact_cdc_and_asof_enrich performs multi-stage compaction in DuckDB:
    • Transport Dedup: Drops duplicate replays by event ID, sorting by timestamp and LSN.
    • LSN Last-Write-Wins: Resolves mutations per primary key by transaction LSN descending, preventing clock skew from reverting committed states.
    • Tombstone Purging: Filters deleted entities (op = 'D') while upserting active deltas into baseline orders.
  3. Point-in-Time FX Enrichment: Pairs transactions with effective exchange rates via ASOF LEFT JOIN, retaining unmapped currencies as NULL for quality gating.
  4. Reconciliation Invariants: Validates row conservation (Final == Base + Inserts - Deletes), primary key uniqueness, tombstone leak prevention, and baseline row identity via SQL EXCEPT.
  5. Audit Reporting: extract_metrics (OutputValues) exposes metrics to flow outputs, and log_compaction_audit logs the scorecard.
  6. Gating & Publishing: reconciliation_gate (If) publishes verified Parquet to Namespace Files (UploadFiles) and writes metadata to the KV store (kv.Set) on pass. When the gate trips (else), halt_corrupt_execution (Fail) aborts the run before promotion; the staging file (staging_compacted_orders.parquet) remains in task outputs for inspection.

What you get

  • In-engine CDC changelog compaction without Spark or Flink clusters.
  • Authoritative WAL LSN Last-Write-Wins ordering and tombstone purging.
  • Point-in-time currency conversion with native DuckDB ASOF LEFT JOIN.
  • Row-conservation and content-integrity reconciliation gates.
  • Table publishing to Namespace Files paired with KV store metadata discovery.

Who it's for

  • Data engineers compacting CDC streams into lakehouses.
  • Analytics engineers reconciling operational stores with analytical Parquet tables.
  • Platform teams establishing automated quality gates at ingestion boundaries.

Why orchestrate this with Kestra

  • Low Operational Footprint: Runs embedded DuckDB in the Kestra worker without external cluster dependencies.
  • Quality Gates: Flow controls (If and Fail) isolate anomalies and halt execution before unverified data reaches consumers.
  • Native Storage & Metadata: Integrates with Kestra Namespace Files for table storage and KV Store for downstream metadata discovery.
  • Complementary Catalog Positioning: Unlike CDC sentinels or ML feature gates, this workflow handles in-engine compaction, LSN ordering, and financial joins.

Prerequisites

  • A running Kestra instance with the DuckDB JDBC plugin (plugin-jdbc-duckdb).
  • No external databases, cloud services, or API secrets required.

Secrets

  • None required.

Quick start

  1. Run Clean Compaction: Execute with default inputs to generate demo data, compact updates, upload lakehouse/compacted_orders.parquet to Namespace Files, and register the KV manifest.
  2. Verify Gate Failure: Execute with inject_corrupt_cdc: true. The pipeline catches unmapped currency ('XYZ') and aborts execution via Fail. The unpromoted staging Parquet remains in task storage for inspection.
  3. Custom Datasets: Supply storage URIs in base_snapshot_uri, cdc_stream_uri, and fx_rates_uri to compact production tables.
  4. Activate the Trigger: Enable the hourly Schedule trigger in the Triggers tab to compact incoming CDC batches periodically.

How to extend

  • Automated Scheduling: Enable the hourly Schedule trigger or attach S3/GCS triggers for continuous compaction.
  • Cloud Storage Landing: Add an aws.s3.Upload or gcp.gcs.Upload task to publish the compacted Parquet file to an external data lake.
  • Alerts & Warehouse Sync: Wire Slack notifications to reconciliation_gate or trigger Snowflake/BigQuery COPY INTO tasks upon completion.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.