# Top Open Source MySQL Migration Tools in 2026

> The top open source MySQL schema migration tools in 2026: Flyway, Liquibase, golang-migrate, dbmate, Sqitch, Skeema, Atlas, and Bytebase compared on approach, MySQL specifics, license, and governance.

Mila | 2026-10-14 | Source: https://www.bytebase.com/blog/top-open-source-mysql-migration-tools/

---

| Update History | Comment |
| -------------- | ------- |
| 2024/02/06 | Initial version. |
| 2026/07/12 | Refresh for 2026: verify all tools still actively maintained, remove stale star chart, move gh-ost coverage to the dedicated online schema change comparison. |
| 2026/10/14 | Expand: add golang-migrate, dbmate, Sqitch, and Atlas, plus a note on ORM-native migrations; group the tools by approach; add what MySQL makes hard (no transactional DDL, table rebuilds, online DDL); per-tool MySQL specifics, license, version, and star counts; Liquibase 5.0's move to the Functional Source License; richer summary table and a how-to-choose section. |

> **Note:** This post is maintained by Bytebase, an open-source database governance platform. We update the post periodically.

MySQL is the most widely deployed open-source relational database, and schema changes on it still hurt. A migration tool decides how your `ALTER TABLE` reaches production: in what order, with what record of what ran, and with what protection against the mistakes MySQL does not forgive. The tools below take three different approaches. The versioned tools run your SQL scripts in sequence. The declarative tools diff the schema you want against the schema you have. And one tool, Bytebase, does both and adds the review, approval, and audit layer around the change.

All of them are actively maintained as of October 2026, and all but one are under an OSI-approved license (the exception is noted under Liquibase):

- [Flyway](#flyway)
- [Liquibase](#liquibase)
- [golang-migrate](#golang-migrate)
- [dbmate](#dbmate)
- [Sqitch](#sqitch)
- [Skeema](#skeema)
- [Atlas](#atlas)
- [Bytebase](#bytebase)

One adjacent category is deliberately excluded: **online schema change** tools like gh-ost and pt-online-schema-change, which rebuild large tables without blocking writes. They complement rather than replace the migration tools below, and several of the tools here can drive them. We compare the two in depth in [gh-ost vs pt-online-schema-change](/blog/gh-ost-vs-pt-online-schema-change/).

## What MySQL makes hard

Three MySQL behaviors shape how every tool on this list works.

**DDL is not transactional.** MySQL 8.0 made each DDL statement atomic, but a migration file with three statements is still three separate commits. If the second one fails, the first one stays applied. Postgres can roll the whole file back; MySQL leaves you with a half-applied schema and a history table that says the migration failed. Every versioned tool below handles this by recording state per migration, and every team using one needs a procedure for repairing a partial run.

**Big `ALTER TABLE` statements rebuild the table.** Changing a column type or adding an index on a 100 GB InnoDB table copies the table, and on the wrong version or with the wrong clause, it blocks writes while doing so. MySQL 8.0 introduced `ALGORITHM=INSTANT` for a growing set of operations (adding a column, dropping a column since 8.0.29, renaming a column), and `ALGORITHM=INPLACE, LOCK=NONE` covers most of the rest. Anything outside that set needs an online schema change tool. Both the current LTS lines, 8.4 and 9.7, support instant DDL; 5.7 does not, and it is out of support.

**Engines and flavors diverge.** MariaDB forked in 2009 and has its own online DDL semantics, its own driver, and its own `ALGORITHM=NOCOPY`. A tool that claims MySQL support may mean Oracle MySQL, MariaDB, Percona Server, Aurora MySQL, or all four. Check before adopting.

## The versioned camp

Versioned tools apply SQL files in order and track which ones have run. The differences are file format, language runtime, and how much help you get when something goes wrong.

### Flyway

[Flyway](https://github.com/flyway/flyway) is the default on the JVM and common everywhere else. You write each change as a numbered SQL file (`V1__create_orders.sql`, `V2__add_index.sql`), and `flyway migrate` applies the pending ones in order and records each in a `flyway_schema_history` table. It ships as a CLI, a Java library, Maven and Gradle plugins, and a Docker image. The engine is Apache-2.0, on the 13.x line, with ~10,100 stars.

![flyway-migration](/content/blog/_shared/flyway-migration.webp)

Two MySQL specifics catch people on first setup. The command-line distribution does not bundle MySQL Connector/J, so you add the driver yourself. It does bundle the MariaDB driver, which Flyway falls back to for MySQL, and since 10.7 that driver rejects `jdbc:mysql://` URLs unless you append `permitMysqlScheme=true`. Once connected, Flyway handles the MySQL-isms well: `DELIMITER` for stored procedures, `#` comments, and unmodified `mysqldump` output all work as migration scripts. Redgate verifies against MySQL 5.7, 8.0, and 9.x.

Redgate bought Flyway in 2019 and kept the Community edition free. The paid Enterprise edition is where undo scripts, drift detection, and bundled code analysis live; Community has no undo, so a failed migration on MySQL means `flyway repair` and a hand-written fix. More in [Bytebase vs. Flyway](/blog/bytebase-vs-flyway/).

### Liquibase

[Liquibase](https://github.com/liquibase/liquibase) is the enterprise incumbent. Changes are `changeset` entries inside a `changelog`, and the canonical format is XML. YAML, JSON, and plain SQL with annotations came later and are fully supported. Java 17 or newer is required since 5.0. ~5,600 stars.

![liquibase-xml](/content/blog/_shared/liquibase-xml.webp)

![liquibase-sql](/content/blog/_shared/liquibase-sql.webp)

The abstraction is the trade. A `createTable` changeset in XML runs on MySQL, Postgres, and Oracle alike, and Liquibase generates the dialect. That matters if MySQL is one of several engines you migrate. If MySQL is the only one, the XML is a tax: a column addition takes a paragraph of markup, and MySQL-specific clauses like `ALGORITHM=INSTANT` need the `modifySql` escape hatch or a raw SQL changeset. Rollback is in the free edition, but for most changes you write the rollback SQL yourself; Liquibase only auto-generates it for changes it can invert, such as a `createTable`.

Two things changed with Liquibase 5.0 in late 2025. First, the license: Liquibase Community moved from Apache-2.0 to the Functional Source License (FSL-1.1-ALv2). You can run it in production and modify it freely, but you cannot offer it as a competing service, and each release reverts to Apache-2.0 two years after it ships. The FSL is not an OSI-approved open source license. Second, the Community distribution no longer bundles drivers or extensions, so like Flyway you add MySQL Connector/J yourself. Paid capabilities moved into the Liquibase Secure line. More in [Bytebase vs. Liquibase](/blog/bytebase-vs-liquibase/).

### golang-migrate

[golang-migrate](https://github.com/golang-migrate/migrate) is the most-starred tool on this list at ~19,000, and the plainest. Each migration is a pair of SQL files, `000001_create_orders.up.sql` and `000001_create_orders.down.sql`. It runs as a single-binary CLI or as a Go library, so a Go service can migrate itself at startup. MIT-licensed, on the 4.x line, and it supports MySQL and MariaDB alongside roughly twenty other databases.

```bash
migrate -source file://db/migrations \
  -database "mysql://app:secret@tcp(127.0.0.1:3306)/orders" up
```

It does exactly what the command says and nothing else. There is no dialect abstraction, no linting, and no dry run. The one MySQL behavior to plan for: when a multi-statement migration fails midway, golang-migrate marks the version as dirty and refuses to continue until you inspect the database and run `migrate force` to set the version by hand. That is the honest response to non-transactional DDL, but it is a manual step.

### dbmate

[dbmate](https://github.com/amacneil/dbmate) is a Go CLI built to be framework-agnostic: a Node, Python, PHP, or Rust team gets the same single binary as a Go team. Each migration is one file with `-- migrate:up` and `-- migrate:down` sections, named by timestamp. MIT-licensed, ~7,500 stars, on the 2.x line, with MySQL, MariaDB, Postgres, SQLite, and ClickHouse support.

```sql
-- migrate:up
ALTER TABLE orders ADD COLUMN shipped_at DATETIME NULL, ALGORITHM=INSTANT;

-- migrate:down
ALTER TABLE orders DROP COLUMN shipped_at, ALGORITHM=INSTANT;
```

The feature that sets it apart is the schema dump. After every `dbmate up`, it shells out to `mysqldump` and writes `db/schema.sql`, which you commit. The diff in a pull request then shows both the migration and the resulting schema, which is the closest a versioned tool gets to the declarative camp's review experience. dbmate wraps each migration in a transaction by default, which on MySQL protects the DML inside a migration but not the DDL.

### Sqitch

[Sqitch](https://github.com/sqitchers/sqitch) is for teams that want plain SQL and no framework. A change is three scripts: `deploy`, `revert`, and `verify`. Instead of a version number, you declare which changes a change depends on, and Sqitch refuses to deploy out of order. It runs the scripts through the native `mysql` client, so anything the client accepts, Sqitch accepts. Perl, MIT-licensed, ~3,200 stars, and no paid edition.

The `verify` script is the MySQL-relevant part. After a deploy, Sqitch runs it to confirm the change actually took, which catches the half-applied migration problem that other tools only report after the fact. Dependencies also hold across projects, so a shared `accounts` schema can be a dependency of the `billing` schema. The cost is a Perl runtime in your pipeline and a smaller ecosystem than Flyway or Liquibase.

### ORM-native migrations

If your schema is defined by an ORM, you may already have a migration tool and not need any of the above. Prisma Migrate, Alembic for SQLAlchemy, Django migrations, Rails Active Record migrations, and Laravel migrations all support MySQL, generate the migration from a change to the model, and track what ran. They are the right default when one application owns the database and the schema follows the code. They stop being the right default when a DBA needs to review the SQL before it runs, when several services share one database, or when a change needs `ALGORITHM=INSTANT` or gh-ost and the generated DDL does not say so. That is what the standalone tools exist for.

## The declarative camp

Declarative tools flip the model. You keep the desired schema in the repository as `CREATE TABLE` statements, and the tool computes the `ALTER` statements needed to get there. There is no migration history, because the repository is the history.

### Skeema

[Skeema](https://github.com/skeema/skeema) is the declarative tool built for MySQL and MariaDB, and nothing else. Go, Apache-2.0, ~1,400 stars, on the 1.14 line.

![skeema](/content/blog/top-open-source-mysql-migration-tools/skeema.webp)

The workflow is four commands. `skeema pull` exports the live schema as one `.sql` file per table. You edit the `CREATE TABLE` to the state you want. `skeema diff` prints the `ALTER TABLE` statements that would bring the database to that state, and `skeema lint` checks them against configurable rules. `skeema push` applies them. The pull request shows the full table definition, not a fragment, so a reviewer sees what the table will look like rather than reconstructing it from a chain of migrations.

Because Skeema targets one engine family, it handles MySQL's online DDL directly. The `alter-algorithm` and `alter-lock` options add `ALGORITHM=INSTANT` or `LOCK=NONE` clauses to the generated statements, and `push` fails rather than silently falling back to a table copy if the clause is unsupported. For tables that need an external tool, `alter-wrapper` routes each `ALTER` through pt-online-schema-change or gh-ost, and `alter-wrapper-min-size` sets the table size above which that happens. The configuration is per environment, so staging can run plain `ALTER` while production goes through gh-ost. GitHub runs its MySQL schema changes this way, with [Skeema plus gh-ost on GitHub Actions](https://github.blog/2020-02-14-automating-mysql-schema-migrations-with-github-actions-and-more/).

The Community edition covers tables, stored procedures, and functions. A paid Premium edition, priced per company, adds views, triggers, events, seed data, and extra linter rules. A hosted Cloud Linter add-on posts diff and lint output on GitHub pull requests. Declarative tooling has one structural limit to keep in mind: a diff cannot express a data backfill or a rename it cannot distinguish from a drop-and-add, so those still need a hand-written step.

### Atlas

[Atlas](https://github.com/ariga/atlas) brings the Terraform model to schema management across engines, MySQL and MariaDB included. You declare the schema you want in SQL, HCL, or straight from an ORM, `atlas schema apply` plans the diff against the live database and applies it after you confirm, and `atlas migrate diff` can instead write that diff out as a versioned migration file for review. So it is declarative and versioned at once, which is the main thing that separates it from Skeema. Go, from Ariga. The core is Apache-2.0, on the 1.x line, with ~8,800 stars.

One mechanic to plan for: Atlas computes the desired state by replaying your schema files on a dev database, typically a throwaway MySQL container passed as `--dev-url`, so the diff is exact for your MySQL version rather than parsed from text. The free tier covers tables, columns, indexes, foreign keys, and constraints, and ships migration linting that flags destructive and backward-incompatible changes plus MySQL and MariaDB specific checks. Views, triggers, stored procedures, drift detection, and custom lint rules are in Atlas Pro, sold per seat through Atlas Cloud.

Against Skeema the trade is clear. Skeema treats MySQL online DDL as configuration and routes big tables through gh-ost; Atlas does not drive an online schema change tool, so large-table changes are still your problem. Atlas in return gives you one model across Postgres, MySQL, SQLite, and more, plus a free planner and linter that none of the versioned tools ship. MySQL-only, pick Skeema. Several engines, pick Atlas. Where Atlas stops is where every CLI tool stops: its lint runs on a laptop or in CI, and nothing in the tool decides who may apply the result to production.

## The governance layer

### Bytebase

Full disclosure: [Bytebase](https://github.com/bytebase/bytebase) is ours. Every tool above applies SQL. Bytebase applies it too, and governs the change around it: who proposed it, what review it passed, who approved it, and what actually ran. Think GitHub or GitLab for database changes, where developers and DBAs collaborate through a web workspace or a GitOps workflow. Go and TypeScript, ~14,600 stars, on the 3.x line. MySQL 5.7 and above, plus MariaDB, Aurora MySQL, and TiDB, alongside Postgres, Oracle, SQL Server, Snowflake, MongoDB, and 28 engines in all.

![issue-detail](/content/blog/top-open-source-postgres-migration-tools/issue-detail.webp)

It covers both camps above. Versioned: submit SQL through the UI or let a pull request drive it through [GitOps](https://docs.bytebase.com/gitops/overview). Declarative: keep `CREATE TABLE` files in the repository and Bytebase generates the `ALTER` statements, for MySQL and Postgres, the same model as Skeema and Atlas. On top of either, [Compare and Sync Schema](https://docs.bytebase.com/change-database/synchronize-schema) diffs one database against others and pushes the DDL to bring them in line, which also serves as schema rollback to an earlier version. [Batch change](https://docs.bytebase.com/change-database/batch-change) applies one change to a database group, the multi-tenant or sharded MySQL case, and the rollout runs stage by stage from dev to staging to production. For `UPDATE` and `DELETE`, a prior backup is taken automatically and a one-click rollback restores the rows.

Before a MySQL change reaches production, Bytebase runs it through [SQL review rules](https://docs.bytebase.com/sql-review/review-rules) that encode the MySQL-specific failures above: require InnoDB, require a primary key, block DDL on tables above a size threshold, restrict charsets and collations, flag `CHANGE COLUMN` and column reordering, and refuse an `UPDATE` or `DELETE` without a `WHERE` clause or above an affected-row limit.

![sql-review](/content/blog/top-open-source-postgres-migration-tools/sql-review.webp)

For the large-table problem, Bytebase wraps gh-ost. Turn on the online migration toggle when creating the change, configure the gh-ost flags, and the ghost-table copy, binlog catch-up, and cut-over run as a single task. It needs row-based binary logging, a primary key on the table, and a primary (not a replica) to run against, and tables with foreign keys or triggers are out, which are gh-ost's own limits.

![bb-issue-ghost-config](/content/blog/top-open-source-mysql-migration-tools/bb-issue-ghost-config.webp)

Three things on this list exist only here. The primary interface is a shared web workspace rather than a CLI, so a DBA who never opens a terminal can review and approve from a browser, and an [approval flow](https://docs.bytebase.com/change-database/approval) routes each change to the right approvers by risk. The change is gated at the point of execution: the review result, the approval, and the rollout log are attached to the change itself, not left in a CI log someone has to find, and every database keeps a changelog of what was applied and by whom. And it covers the query path as well as the change path, with a SQL Editor that enforces data access control and dynamic data masking. One [audit log](https://docs.bytebase.com/security/audit-log) records both paths, so who ran what against production, whether a migration or an ad hoc query, is one question with one answer, exportable for SOC 2, GDPR, and HIPAA reviews. The versioned tools record which migration ran and under which database account, usually a shared one; none of them records which person ran it or what else that person did.

![sql-editor](/content/blog/top-open-source-postgres-migration-tools/sql-editor.webp)

Everything in the change path, from declarative migration and schema sync to batch change, SQL review, gh-ost, and rollback, is in the free Community edition, as is the SQL Editor. Approval flow, risk assessment, data masking, and the audit log (7-day retention in Pro, unlimited in Enterprise) are in the paid tiers; see [pricing](/pricing/). Against Atlas: Atlas's planner is the more mature one, with HCL, ORM loaders, and dev-database replay, while Bytebase's declarative mode covers the schema objects most MySQL teams change. Where Bytebase is the only option is everything after the plan: review, approval, staged rollout, and the record of who did what. Teams run both, with Atlas or Flyway generating the migration and Bytebase governing the rollout. More in [Bytebase vs. Atlas](/blog/bytebase-vs-atlas/).

## Summary

| Tool | Approach | Interface | Language | MySQL + MariaDB | Online DDL handling | Lint / review | License |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Flyway | Versioned SQL | CLI + library | Java | Both | Whatever your SQL says | SQLFluff; bundled rules paid | Apache-2.0 core, paid |
| Liquibase | Versioned changesets | CLI + library | Java | Both | `modifySql` or raw SQL changeset | Policy checks paid | FSL core, paid |
| golang-migrate | Versioned up/down SQL | CLI + library | Go | Both | Whatever your SQL says | None | MIT |
| dbmate | Versioned SQL + schema dump | CLI | Go | Both | Whatever your SQL says | None | MIT |
| Sqitch | Versioned, dependency-based | CLI | Perl | Both | Whatever your SQL says | `verify` scripts | MIT |
| Skeema | Declarative | CLI | Go | Both | `ALGORITHM`/`LOCK` clauses, gh-ost/pt-osc | 18 rules free, more paid | Apache-2.0 core, paid |
| Atlas | Declarative + versioned | CLI | Go | Both | Generated DDL, no online tool | Basic lint free, custom rules paid | Apache-2.0 core, paid |
| Bytebase | Versioned + declarative, governed | GUI + GitOps | Go + TypeScript | Both | Built-in gh-ost | 200+ rules free | OSS core, paid |

## How to choose

**One engine, SQL-first, small team.** Flyway if you are on the JVM, golang-migrate or dbmate if you are not and want a single binary. dbmate's schema dump makes review noticeably easier at no cost.

**Several engines, MySQL among them.** Liquibase if you want versioned changelogs and the license change is acceptable; its abstraction is the only one here that targets MySQL and Oracle from the same file. Atlas if you want desired-state planning across engines with a free linter.

**MySQL only, and you think in desired state.** Skeema. Nothing else on this list understands `ALGORITHM=INSTANT` and gh-ost thresholds as configuration rather than as text you paste into every migration.

**Schema owned by one application's ORM.** Stay with the ORM's own migrations until a DBA review step or a shared database forces the move.

**More than a few people touching production.** The bottleneck stops being which tool applies the SQL and becomes who is allowed to run a change, who approved it, and whether what ran matched what was reviewed. None of the versioned or declarative tools do that. That is the layer Bytebase provides, alone or alongside any of them. The [MySQL schema migration best practices](/blog/mysql-schema-migration-best-practice/) post covers the operating procedure regardless of which tool you pick.

## References

- [MySQL 8.4 Reference Manual: Online DDL Operations](https://dev.mysql.com/doc/refman/8.4/en/innodb-online-ddl.html)
- [Automating MySQL schema migrations with GitHub Actions and more](https://github.blog/2020-02-14-automating-mysql-schema-migrations-with-github-actions-and-more/)
- [Liquibase Community and the Functional Source License](https://www.liquibase.com/blog/liquibase-community-for-the-future-fsl)
- [Flyway MySQL database driver reference](https://documentation.red-gate.com/flyway/reference/database-driver-reference/mysql)
- [How to install local MySQL on Mac, Ubuntu, CentOS, Windows](/reference/mysql/how-to/how-to-install-mysql-on-mac-ubuntu-centos-windows/)

## Related reading

- [MySQL Online DDL: A Practical Guide](https://www.bytebase.com/blog/mysql-online-ddl/)
- [gh-ost vs pt-online-schema-change](https://www.bytebase.com/blog/gh-ost-vs-pt-online-schema-change/)
- [MySQL Schema Migration Best Practice](https://www.bytebase.com/blog/mysql-schema-migration-best-practice/)
- [Flyway vs. Liquibase: The Definitive Comparison in 2026](https://www.bytebase.com/blog/flyway-vs-liquibase/)
- [Top 7 MySQL Schema Compare Tools to Diff and Sync Databases in 2026](https://www.bytebase.com/blog/top-mysql-schema-compare-tools/)
- [Bytebase vs. Atlas: a side-by-side comparison for database schema migration](https://www.bytebase.com/blog/bytebase-vs-atlas/)
- [Top Open Source Postgres Migration Tools in 2026](https://www.bytebase.com/blog/top-open-source-postgres-migration-tools/)