All articles
EngineeringJune 11, 2026·8 min read

How We Live-Certified All 49 Database Migration Paths

DBShifts Engineering

The team building the migration platform

DBShifts supports MySQL, MariaDB, PostgreSQL, SQL Server, Oracle, SQLite and MongoDB. That's 7 sources × 7 targets = 49 migration paths — and "supports" is a word that's easy to put on a landing page and hard to make true. Most migration tools verify two or three popular pairs and assume the type mapper covers the rest. We decided that nothing ships as supported until a live migration of that exact pair passes verification end-to-end.

The certification fixture

Every certification run starts by seeding the source engine with a fixture written in its native dialect: three tables covering a foreign-key relationship, an index, and a wide cert_types table holding every type group the engine supports — integers in all widths, unsigned variants, fixed-precision decimals, floats, CHAR/VARCHAR/TEXT, binary and BLOB, dates, times, timestamps with and without timezones, booleans, JSON, ENUM/SET, UUID, arrays, network types.

The rows matter as much as the columns. Each fixture includes:

  • a typical row — the happy path,
  • an all-NULL row — nullability survives the trip,
  • an extremes row — BIGINT max, max decimal precision, year-1000 timestamps,
  • a multi-byte row — CJK text, emoji, a 2 KB string,
  • a zero/empty row — empty strings, zero dates, empty byte arrays.

The run

For each pair the harness drives the exact code path a production migration uses — introspection, schema conversion, batched transfer with FK deferral, index rebuild — then validates with per-table row counts and an order-independent, type-aware checksum of every row on both sides. Lossy type conversions and objects routed to manual review are captured into the report, so "passed" means counted, hashed, and accounted for.

$ certify_pairs --pairs all
[34/49] oracle → mssql ... pass (1.9s)
[35/49] oracle → sqlite ... pass (1.8s)
...
49/49 pairs passed

What the harness caught

The first full run passed 7 of 49 pairs. The other 42 failures decomposed into about twenty-five real bugs — silent truncation, dropped columns, poisoned connections, lossy float fetches — most of which would have been production data-loss incidents. (We wrote up the worst offenders in a separate post.) After fixing every cluster and re-running until green, the matrix went 49/49.

Certified vs Beta in DBShifts: certified pairs (MySQL ↔ PostgreSQL, every same-engine pair, MySQL ↔ MariaDB) are battle-tested beyond the harness. Beta pairs all passed the same live certification — they're labelled Beta until they've seen more production mileage, and every migration still ends with a fidelity report you can audit.

Why this matters for you

When you point DBShifts at an Oracle source and a SQLite target — the kind of pair nobody advertises — you're not the first to run it. A live migration of that exact combination, with edge-case data designed to break it, passed counts and checksums before the pair was enabled. That's the bar every pair has to clear, every time we change the engine.

Migrate with the platform behind these posts

All 49 engine pairs live-tested. Validation, rollback, and CDC built in.

Start Free Migration