Data Migration Patterns¶
Each bounded context extraction requires migrating data from the shared Oracle monolith database into a service-owned store. This document covers the three patterns used and their applicability.
Pattern 1: CDC via Debezium (Historical Data)¶
Used to bootstrap a new service's data store with existing records from Oracle without downtime.
Process: 1. Deploy the Debezium Oracle connector pointed at the source table. 2. Debezium performs a full table snapshot — all existing rows become change events. 3. The bootstrap consumer writes each event into the new service's Postgres schema, applying any necessary transformations (column renames, type coercions, normalization). 4. Ongoing changes are captured as incremental CDC events until the dual-write phase begins.
Go-condition for Phase 3 (Inventory): CDC lag < 1 second for 30 consecutive minutes before traffic canary starts.
Pattern 2: Dual-Write (Transition Window)¶
Used during the canary traffic ramp to guarantee no data is lost if a rollback is required.
Process:
1. New service receives writes (from the canary percentage of traffic).
2. A sidecar relay also writes the same mutation to Oracle via the monolith's internal API.
3. A reconciliation job (tooling/reconcile-dual-write.py) compares row counts and checksums between Oracle and the new store every 5 minutes.
4. If divergence > 0.1%, the reconciliation job pages on-call and halts canary advancement.
Invariant: Neither store is the "source of truth" during dual-write. Rollback is always possible because Oracle is still consistent.
Pattern 3: Event Replay (Orders — Event Sourcing)¶
The Orders domain does not migrate rows — it migrates business events. Historical orders are replayed from Oracle's audit tables as synthetic domain events into EventStoreDB.
Process:
1. tooling/backfill-orders-eventstore.py reads the Oracle orders and order_audit tables.
2. For each order, it reconstructs the event sequence (OrderPlaced → OrderConfirmed | OrderCancelled) from the audit timestamps.
3. Events are appended to EventStoreDB streams. Optimistic concurrency (expected version = stream position) prevents duplicates on retry.
4. Projections are rebuilt from the backfilled streams before traffic is cut over.
Note: Financial reconciliation must validate that the projected order totals from EventStoreDB match Oracle to the cent before Phase 4 traffic canary begins.
Rollback Procedures¶
For all phases, data migration rollback means: 1. Stop canary traffic (set Kong weight to 0 for the new service's paths). 2. Allow dual-write to drain (reconciliation job confirms Oracle is consistent). 3. Decommission the new service's Debezium connector and bootstrap consumer.
The monolith Oracle database is never modified during extraction — it is always the safe fallback state.
See also: Migration Strategy Overview