mysql
mysql

Migrate MySQL to MySQL

Certified — live-tested path

Same-engine MySQL migrations are how you move between hosts, clouds, or versions — and they still fail in the boring ways: half-copied tables, stale sequences, missing indexes. DBShifts moves the schema and every row, defers constraints for speed, reseeds counters, and proves the result with row counts and checksums.

Start MySQL → MySQL Migration

Free tier · no credit card

How the migration works

01

Connect

Point DBShifts at your source and target. Credentials stay encrypted; SSH tunnels supported for private databases.

02

Analyze

Automatic schema introspection produces a migration plan: what converts automatically, what migrates with warnings, what needs human review.

03

Migrate

Schema is created on the target, data transfers in parallel batches with constraints deferred, indexes rebuilt after load.

04

Validate

Per-table row counts, type-aware checksums on both sides, FK integrity — plus a fidelity report listing anything lossy.

Upgrading 5.7 to 8.0 changes the default character set and collation

MySQL 8.0 defaults to utf8mb4 with the utf8mb4_0900_ai_ci collation, where 5.7 defaulted to latin1. Tables you copy keep the character set they were declared with, but anything created on the new server without an explicit one gets the new default. Joining an old latin1 or utf8mb4_general_ci column to a new utf8mb4_0900_ai_ci one fails with 'Illegal mix of collations'.

That collation also does not exist on 5.7, so a dump taken from 8.0 cannot be restored onto, or replicated to, an older server without rewriting it. Decide the target collation before the move and set it on the database explicitly, rather than fixing tables one by one afterwards.

utf8 is three bytes, and the index limit bites when you fix it

In MySQL, utf8 means utf8mb3: at most three bytes per character, so emoji and some CJK characters cannot be stored. A same-engine move is the natural time to convert to utf8mb4, and the conversion is where index limits appear, because a VARCHAR(255) in utf8mb4 can need 1,020 bytes of index key.

InnoDB allows 3,072 bytes per index key with the DYNAMIC or COMPRESSED row format, the default since 5.7, but only 767 bytes with the older COMPACT and REDUNDANT formats. Tables created long ago may still use those, and converting them fails until the row format changes too.

Authentication changes break old clients before any query runs

MySQL 8.0 creates users with caching_sha2_password by default. Client libraries that only know mysql_native_password fail at connect time with 'Authentication plugin caching_sha2_password cannot be loaded', which looks like a network or password problem and is neither.

Check every driver that connects before the cutover, not after. Recreating users with mysql_native_password is only a stopgap: MySQL 8.4 no longer enables that plugin by default, so the lasting fix is upgrading the drivers.

MySQL → MySQL conversion notes

Engine-specific rules baked into the conversion and transfer pipeline — verified by live certification of this exact pair.

  • TINYINT(1) is treated as a boolean; plain TINYINT stays numeric — converting both blindly corrupts ratings and counters.
  • UNSIGNED integers are widened on targets without unsigned types, so values above the signed range survive.
  • ENUM and SET columns are converted with their value lists preserved (native enums, CHECK constraints, or arrays depending on the target).
  • TIME columns are durations (-838h..838h) at the driver level — DBShifts converts them per target instead of failing the batch.
  • Zero dates (0000-00-00) are normalized deterministically and reported, never silently dropped.

Frequently asked questions

Is MySQL to MySQL migration production-ready in DBShifts?

Yes — MySQL to MySQL is a certified pair. It passed DBShifts's live certification suite (schema conversion, data transfer, row counts, type-aware checksums over an edge-case fixture) and is battle-tested in production use.

How does DBShifts verify the MySQL to MySQL migration was correct?

Three layers: per-table row counts on both sides, an order-independent type-aware checksum of row data (canonicalized so engine representation differences don't false-alarm), and FK integrity checks on the target. Rows that fail to insert are quarantined with the exact error — never silently dropped — and can be fixed and retried from the UI.

What happens to MySQL types that MySQL doesn't have?

They convert by deterministic rules with a recorded decision: a native equivalent where one exists, a portable fallback (TEXT/JSON/DECIMAL) where one doesn't. Every lossy conversion appears in the migration plan before you run and in the fidelity report after. You can override any mapping per column.

Can I keep MySQL and MySQL in sync after the initial migration?

Yes. DBShifts supports incremental sync (UPSERT-based delta transfers on a sync key) and, for supported sources, real-time change data capture so the target stays current until you cut over.

Do I need to write any SQL or scripts for MySQL to MySQL?

No. Connect both databases, review the generated migration plan (what's automatic, what migrates with warnings, what needs manual review — typically triggers and stored procedures), and run. Procedural code is transpiled best-effort and queued for human review rather than auto-applied.

What changes in a same-engine MySQL migration?

Structurally nothing changes — types map one-to-one. The risks are operational: half-copied tables, sequences left pointing at 1, and indexes that never got rebuilt. DBShifts reseeds counters to MAX(id)+1, defers then rebuilds constraints and indexes, and proves the copy with row counts and checksums.

Go deeper

Related migration paths

Ready to move MySQL to MySQL?

Set up in under two minutes. Validation and rollback included.

Start Free Migration