Skip to content

PATTERN Cited by 2 sources

Cross-engine database migration audit

Cross-engine database migration audit is a pre-migration pattern: before moving a schema between two SQL engines (e.g. PostgreSQL → MySQL), enumerate the differences along three orthogonal axes and confirm every source construct maps to a supported target construct.

The axes — from Adnan Kukic's PlanetScale audit (sources/2026-04-21-planetscale-migrating-from-postgres-to-mysql) — are:

  1. Column-type axis — does every source column have a target equivalent? Does the equivalent behave the same way at the representation level, not just the declaration level?
  2. DDL/DML dialect axis — do CREATE, DROP, TRUNCATE, INSERT, ON CONFLICT / ON DUPLICATE KEY, stored procedures, triggers, views, and partitioning translate cleanly?
  3. Operational-semantics axis — identifier case sensitivity, transaction safety of DDL statements, extension ecosystems, sequence / auto-increment semantics.

Worked example: Postgres → MySQL audit

The canonical wiki instance is the 2023 PlanetScale post. Three sample tables surface three column-type classes:

Five operational-dialect gaps are called out:

Why this pattern is distinct from a same-engine upgrade

The PlanetScale sources/2026-04-21-planetscale-how-to-upgrade-from-mysql-57-to-80 audit enumerates within-engine breaking changes across a major-version bump (MySQL 5.7 → 8.0). The cross-engine audit applies the same discipline across engines, and picks up a further class of surprises — the representation-layer differences (MySQL WKB for POINT) that a version-bump audit would never surface because the representation doesn't change across MySQL versions.

What the pattern does not cover

A cross-engine migration audit is a schema + dialect readiness check. It does not address:

Exit criteria

Audit is complete when:

  • Every source column type has a declared target equivalent, including representation (not just declaration).
  • Every DDL / DML statement in the application's query log has a confirmed target-engine form, or a planned application-side rewrite.
  • Every stored procedure, trigger, and extension is either ported or explicitly dropped from the migration scope.
  • Identifier collisions under the target engine's case rules have been resolved.
  • EXPLAIN output on the target engine for top-N queries has been spot-checked against Postgres's expectations.

See also

Last updated · 378 distilled / 1,213 read