How to Migrate from Managed to Self-Managed MySQL

Validated on 14 May 2026 • Last edited on 14 May 2026

MySQL is an open source, object-relational database built with speed and reliability in mind. Its large and active developer community has created many third-party applications, tools, and libraries that expand MySQL’s functionality.

You can migrate a DigitalOcean Managed MySQL cluster to a self-managed MySQL deployment (for example, on a Droplet). This process exports data from the managed cluster and imports it into a MySQL instance that you control. It does not apply to migrations between managed clusters.

This process uses the third-party Aiven MySQL migration utility (Apache License 2.0). Review the project README for details on requirements, limitations, flags, and behavior. As with any migration, validate the process in a non-production environment first and run only commands you trust.

Warning
Third-party tools can change. Confirm compatibility with your MySQL versions and environment before production use.

Prerequisites

Before you begin, make sure you have:

  • Access to the source cluster (DigitalOcean Managed MySQL), including the default admin user doadmin and its password. You can find connection details on the cluster’s Overview tab or using the API.
  • A target MySQL server you manage (MySQL 8.0 or newer as required by the upstream tool), with an administrative user for importing data and configuring replication.
  • SSH or console access to the host where you will run the migration tool (typically the target host or another trusted system), with permission to install Python packages.
  • Network connectivity from that host to both the source cluster and the target database. This may require adding the host to trusted sources, configuring VPC access, and updating firewall rules as needed.

Managed MySQL typically uses port 25060 for client connections. See connection details for your cluster.

Step 1: Install aiven-mysql-migrate

On the host where you plan to run the migration (often the Droplet running the target MySQL server), log in as a user with permission to install software. Then create a working directory, clone the repository, and install the tool in a virtual environment:

git clone https://github.com/Aiven-Open/aiven-mysql-migrate.git
cd aiven-mysql-migrate
python3 -m venv myenv
source myenv/bin/activate
pip3 install -r requirements-dev.txt
pip3 install .

If pip3 install . fails with an error referencing version = get_version(...) in setup.py, set a static version (for example version = "1.0.0") and run pip3 install . again.

Step 2: Verify the CLI and Set Connection URIs

Confirm the CLI is available:

mysql_migrate --help

Set environment variables for the migration. The tool reads credentials from the environment to avoid exposing them in process listings. Use URI formats described in the upstream README. Set ssl-mode to REQUIRED.

export SOURCE_SERVICE_URI="mysql://doadmin:<password>@<source-host>:25060/<database>?ssl-mode=REQUIRED"
export TARGET_SERVICE_URI="mysql://<user>:<password>@<target-host>:<port>/<database>?ssl-mode=REQUIRED"
export TARGET_MASTER_SERVICE_URI="mysql://<user>:<password>@<target-host>:<port>/<database>?ssl-mode=REQUIRED"
  • SOURCE_SERVICE_URI: The managed cluster. Use doadmin, the cluster hostname, and port from the Control Panel.
  • TARGET_SERVICE_URI: The self-managed MySQL instance used for import.
  • TARGET_MASTER_SERVICE_URI: The account used to manage replication on the target. This is often the same host and database as TARGET_SERVICE_URI, but with additional replication privileges. If omitted, the tool performs a dump-only migration.

Update hostnames, ports, database names, and users to match your environment.

Step 3: Prepare the Destination MySQL Server

On the target MySQL instance, enable GTID so replication-based migration can run. Connect as a user with permission to set global variables (for example root) and run:

SET GLOBAL enforce_gtid_consistency = ON;
SET GLOBAL gtid_mode = OFF_PERMISSIVE;
SET GLOBAL gtid_mode = ON_PERMISSIVE;
SET GLOBAL gtid_mode = ON;

If GTID or other preconditions are not met, the tool may fall back to a mysqldump-only migration, which captures the database at a single point in time. Writes that continue on the source during or after the export are not replicated into the target the way they are with replication-based migration, which can mean missing data on the target, a longer maintenance window, or more downtime while you coordinate a clean cutover. See the upstream documentation for details.

Step 4: Validate the Migration Setup

With the virtual environment activated and variables exported, run:

mysql_migrate --validate-only

Sample output:

2025-04-11 13:16:47,725 aiven_mysql_migrate.main    INFO    MySQL migration from db-mysql-nyc3-00000-do-user-00000000-0.k.db.ondigitalocean.com to 192.0.2.10
. . .
2025-04-11 13:16:47,725 aiven_mysql_migrate.main    INFO    Starting pre-checks
. . .
2025-04-11 13:16:55,803 aiven_mysql_migrate.main    INFO    All pre-checks passed successfully.

WARNING lines from MySQL client tools (for example passwords on the command line or deprecated flags) often appear during a normal run and can be ignored when the log ends with All pre-checks passed successfully.

When replication is unavailable, aiven-mysql-migrate emits a WARNING that mentions falling back to dump. It often includes a details: suffix for failed pre-checks, or a different WARNING if TARGET_MASTER_SERVICE_URI is unset, and an INFO line stating that the replication method is not available. See the upstream README for details.

Step 5: Run the Migration

Before cutover, schedule a window to stop application writes to the source. Replication-based migration can catch up to reduce lag, but dump-only migration requires a consistent source during export.

Run the migration:

mysql_migrate --seconds-behind-master 0 --stop-replication
  • --seconds-behind-master waits until replication lag is within the specified threshold.
  • --stop-replication stops replication after completion. Without it, replication continues until you stop it manually.

See mysql_migrate --help and the upstream README for options such as --filter-dbs.

Next Steps

We can't find any results for your search.

Try using different keywords or simplifying your search terms.