- Same engine, small database, a maintenance window available: use the engine's own dump and restore (pg_dump/pg_restore, mysqldump, SQL Server backup and restore). It is the simplest method with the fewest moving parts.
- Different engine: convert the schema first (DMS Schema Conversion, SSMA, pgloader or Ora2Pg), then move the data, then fix what the tool could not convert, usually stored procedures, triggers and engine-specific SQL.
- Little or no downtime: copy the bulk of the data while the source stays live and replicate ongoing changes (for example AWS DMS full load plus CDC), then switch over in a short window.
- Validate with row counts and simple aggregates on both sides before the switch, and decide in advance what result would make you roll back.
- "Database migration" also means versioned schema changes applied by tools such as Flyway; that is a different job, covered briefly at the end.
What is database migration?
In operations, database migration (often shortened to db migration) means moving a database from one place to another: to a new server or data centre, to a newer engine version, to a managed cloud service such as Amazon RDS or Azure SQL, or to a different engine altogether, for example SQL Server or MySQL to PostgreSQL, or Oracle to PostgreSQL. The first three are homogeneous migrations (same engine); the last is heterogeneous and adds schema and code conversion.
In application development the same phrase means something else: a versioned script that changes the schema (add a column, create an index) and is applied in order to every environment. Both meanings are covered here, the first in depth, the second in the last section.
The database migration process, step by step
The six steps below apply to any engine or platform. Our database migration checklist breaks each one into individual checks you can tick off.
| Step | What you do | Output |
|---|---|---|
| 1. Assess | Inventory databases, sizes, versions, features used, dependent applications and jobs; agree the allowed downtime | Scope, method (offline or online) and a target design |
| 2. Convert the schema | For a new engine, convert tables, types, indexes, views and code; for the same engine, script or restore the schema | Target schema plus a list of objects needing manual work |
| 3. Move the data | Dump and restore, bulk load, or full load plus change replication | Target populated and, for online moves, kept in sync |
| 4. Validate | Compare row counts, aggregates and sample rows; run the application test suite against the target | Signed-off comparison |
| 5. Cut over | Stop writes, apply the last changes, reset sequences, switch connection strings | Application running on the target |
| 6. Roll back if needed | Keep the source intact and a decision point agreed in advance | A rehearsed way back |
Assess before you choose a tool
The assessment decides everything else. Record the source engine and edition (AWS DMS, for instance, cannot read changes from SQL Server Express), total size and the largest tables, data types that have no direct equivalent on the target, stored procedures and triggers, and every application, report and job that connects. Engine-specific tools produce an assessment report for you: DMS Schema Conversion and SSMA both estimate how much converts automatically and what needs manual work.
Convert the schema
For a same-engine move, the schema travels with the dump or backup. For a heterogeneous move, convert it with a tool built for the pair: DMS Schema Conversion for several sources into Amazon RDS, Aurora or Redshift; SSMA for Oracle, MySQL, Access, Db2 and SAP ASE into SQL Server or Azure SQL; pgloader for MySQL, SQL Server and SQLite into PostgreSQL; Ora2Pg for Oracle (and MySQL) into PostgreSQL. Expect manual work on procedural code: T-SQL or PL/SQL procedures rarely convert line for line.
Move the data
Load the data with constraints and secondary indexes off where the tool allows it, and build them afterwards; AWS gives this advice for large DMS full loads, and pg_restore's parallel jobs speed up index and constraint creation. For an online migration, start change capture before or with the bulk copy so nothing written during the copy is lost.
Validate, cut over and plan the rollback
Compare the two sides table by table (see the worked example below), then run the application against the target. At cutover, stop writes to the source, let the last changes apply, set each sequence or identity on the target past the highest value copied, and switch the connection string. Keep the source unchanged and readable until you are confident; the rollback plan is simply pointing the application back, so agree beforehand which failures would trigger it and how long the window stays open.
Offline or online migration: choosing a method
Offline (dump and restore). Stop the application, take a consistent export, restore it on the target, validate, switch. pg_dump makes consistent exports even while the database is in use, and mysqldump's --single-transaction option dumps InnoDB tables inside one transaction. Downtime equals export plus transfer plus restore plus checks, so it suits databases that copy within your maintenance window.
Online (replicate, then switch). Copy the data while the source stays live, keep applying changes, and switch in a short window. Options include a managed service (AWS DMS full load plus CDC, Azure Database Migration Service online mode for SQL Managed Instance) or the engine's own replication for same-engine moves. It costs more effort and needs keys on every table, but downtime shrinks to the final switch.
Database migration tools compared
Choose by source, target and whether you need ongoing replication. All of the tools below are free to download or use except the managed services, which bill for the capacity they run on.
| Tool | Sources to targets | Schema conversion | Ongoing changes | Best for |
|---|---|---|---|---|
| pg_dump / pg_restore | PostgreSQL to PostgreSQL | Same engine only | No | Moves, upgrades and copies of PostgreSQL; see pgAdmin for a GUI |
| mysqldump | MySQL to MySQL (SQL text output) | Same engine only | No | Small and medium MySQL moves |
| SQL Server backup/restore, bcp | SQL Server to SQL Server; bcp copies table data to and from files | Same engine only | No | Moving SQL Server between servers or versions; see SSMS |
| AWS DMS (+ DMS Schema Conversion) | Many engines into and within AWS | Yes, with DMS Schema Conversion or AWS SCT | Yes (CDC) | Low-downtime moves into AWS; see the AWS DMS guide |
| Azure Database Migration Service | SQL Server to Azure SQL Database, Managed Instance or SQL Server on Azure VMs | Schemas, not code conversion between engines | Online mode for Managed Instance and Azure VMs | Moving SQL Server into Azure |
| SQL Server Migration Assistant (SSMA) | Oracle, MySQL, Access, Db2, SAP ASE to SQL Server or Azure SQL | Yes | No | Moving to the Microsoft platform |
| pgloader | MySQL, SQL Server, SQLite and files to PostgreSQL | Yes, with casting rules | No | One-command MySQL or SQL Server to PostgreSQL loads |
| Ora2Pg | Oracle (and MySQL) to PostgreSQL | Yes, including PL/SQL to PL/pgSQL | No (offline data copy) | Oracle to PostgreSQL |
| Flyway | Versioned SQL scripts to most engines | Not applicable | Not applicable | Schema changes across environments |
Worked example: an offline PostgreSQL move with validation
The simplest real migration is a same-engine move, for example a PostgreSQL database moving to a new server or to a managed service. The commands follow the examples in the PostgreSQL documentation: dump to a custom-format archive, create an empty database from template0, and restore with parallel jobs. --no-owner is useful when the target uses different role names, as managed services usually do. For MySQL the equivalent is mysqldump, and for SQL Server a native backup and restore; the pg_dump and mysqldump guides in the related pages cover the options in full.
Run the validation query on both sides and compare the output. Matching counts, sums and key ranges do not prove every value is identical, but they catch missing batches, truncated loads and duplicate inserts quickly; add a sample of rows compared column by column for critical tables.
# 1. On the source (application stopped or read-only)
pg_dump -h <source-host> -U <user> -Fc mydb > mydb.dump
# 2. On the target: empty database, then a parallel restore
createdb -h <target-host> -U <user> -T template0 mydb
pg_restore -h <target-host> -U <user> -d mydb -j 4 --no-owner mydb.dumpSELECT COUNT(*) AS row_count,
SUM(total_amount) AS total_amount,
MIN(order_id) AS min_id,
MAX(order_id) AS max_id
FROM orders;Common migration scenarios
- SQL Server to PostgreSQL: type mapping, T-SQL to PL/pgSQL, and the choice between pgloader, AWS DMS with Schema Conversion, and Babelfish for Aurora PostgreSQL. See the SQL Server to PostgreSQL migration guide.
- MySQL to PostgreSQL: pgloader in one command, AUTO_INCREMENT to identity columns, zero dates and case sensitivity. See the MySQL to PostgreSQL migration guide.
- Oracle, MySQL or Access to SQL Server or Azure SQL: SSMA. See the SQL Server Migration Assistant guide.
- Oracle database migration from on-premises to the AWS cloud: DMS Schema Conversion converts Oracle schemas for Aurora or RDS for PostgreSQL or MySQL, and AWS DMS moves the data with optional CDC. Ora2Pg is the open-source route to PostgreSQL.
- Azure database migration: Azure Database Migration Service for SQL Server into Azure SQL Database or Managed Instance; SSMA when the source is not SQL Server.
- DynamoDB migration: Amazon DynamoDB is one of AWS DMS's documented targets, so relational data can be loaded into it with a DMS task; plan the key design first, because tables do not map one to one.
Schema migrations: the other meaning of "database migration"
Development teams use "migrations" for the scripts that evolve a schema over time. Flyway, for example, describes migrations as SQL scripts that capture schema and data changes, are kept in version control and are run in the same order in every environment. Its migrate command compares the scripts with a schema history table in the database and applies only those not yet run, so a database at version 5 with scripts up to version 9 receives 6, 7, 8 and 9. Versioned migrations can have matching undo migrations, and repeatable migrations are re-applied when they change.
Frameworks in most languages ship their own migration runners, including ones for document databases such as MongoDB; the idea is the same: small, ordered, version-controlled changes. Use schema migrations for day-to-day changes, and the process above when the whole database moves.
Next steps
Before a heterogeneous migration, read the engine comparison so you know which features will need rework: SQL Server vs PostgreSQL, MySQL vs PostgreSQL or PostgreSQL vs Oracle. If you are new to SQL or need a refresher on the statements used to check a migration, start with the SQL beginner course.
Frequently asked questions
What are the steps of a database migration?
Assess the source and choose a method, convert the schema (only needed when the engine changes), move the data, validate it against the source, cut over, and keep a rollback route until the new system is proven.
How long does a database migration take?
It depends on data volume, network speed, the amount of code to convert and the testing required. For offline moves, downtime is roughly export plus transfer plus restore plus checks; for online moves, the downtime is only the final switch, but preparation takes longer.
What is the best database migration tool?
There is no single best tool. For the same engine, the native dump or backup tools are simplest. For a new engine, use the converter built for that pair (SSMA, pgloader, Ora2Pg or DMS Schema Conversion), and add AWS DMS or Azure Database Migration Service when you need ongoing replication or a managed service.
How do I migrate a database with zero downtime?
Strictly zero is rare. The usual approach is full load plus change data capture: copy the data while the source stays live, keep applying changes, then stop writes briefly, let replication catch up and switch connections. The switch itself takes seconds to minutes.
What is the difference between a database migration and a schema migration?
A database migration moves the whole database to a new server, version, platform or engine. A schema migration is a versioned script, managed by a tool such as Flyway, that changes the structure of an existing database in a controlled order.
Sources
- PostgreSQL documentation: pg_dump
- PostgreSQL documentation: pg_restore
- PostgreSQL versioning policy
- MySQL 8.4 Reference Manual: mysqldump
- Microsoft Learn: bcp utility
- Microsoft Learn: Back up and restore of SQL Server databases
- Microsoft Learn: SQL Server Migration Assistant
- Microsoft Learn: What is Azure Database Migration Service?
- AWS DMS User Guide: What is AWS DMS?
- AWS DMS User Guide: Best practices
- AWS DMS User Guide: Targets for data migration
- AWS DMS User Guide: DMS Schema Conversion
- pgloader documentation
- pgloader releases (GitHub)
- Ora2Pg home page
- Ora2Pg documentation
- Redgate Flyway documentation: Migrations
Checked 8 October 2026.
How we research guides: our editorial method. We link only to official downloads and never host installers.