Home / Databases / MySQL

DatabasesRunbookAdvanced

Transformation: MySQL to Aurora MySQL with XtraBackup restore from S3 and binlog replication

Move a large self-managed or RDS MySQL database to Aurora MySQL with minimal downtime. From RDS, use an Aurora read replica. From EC2 or on-premises, restore a Percona XtraBackup from S3 and then replicate binlogs until cut-over.

Deepak Bhardwaj3 min read

Applies toMySQL 5.7/8.0 sources; Amazon Aurora MySQL-Compatible version 3 (MySQL 8.0 compatible); check current supported versions

Pick the path

Source Path Downtime
RDS for MySQL Create an Aurora read replica of the RDS instance, then promote Minutes
EC2 / on-premises, large XtraBackup → S3 → restore into Aurora, then binlog replication Minutes
Any, small mysqldump/MySQL Shell dump & load Full duration
Any, heterogeneous needs AWS DMS Minutes

Path A: from RDS for MySQL

aws rds create-db-cluster --db-cluster-identifier shop-aurora --engine aurora-mysql \
  --replication-source-identifier arn:aws:rds:eu-west-1:111122223333:db:shop-rds \
  --db-subnet-group-name db-subnets --vpc-security-group-ids sg-0abc
aws rds create-db-instance --db-instance-identifier shop-aurora-1 --db-cluster-identifier shop-aurora \
  --engine aurora-mysql --db-instance-class db.r7g.xlarge

When ReplicaLag is near zero: stop writes, wait for 0, then promote:

aws rds promote-read-replica-db-cluster --db-cluster-identifier shop-aurora

Path B: from EC2 / on-premises

1. Physical backup to S3

xtrabackup --backup --user=backup --password=*** --stream=xbstream --target-dir=/tmp/xb \
  | aws s3 cp - s3://shop-migr/backup/shop.xbstream

Aurora's "restore from S3" supports specific XtraBackup and MySQL versions and formats (full backups; check the docs for compression/streaming support). Many teams back up to local disk, then upload the files.

Record the binlog position / GTID from xtrabackup_binlog_info.

2. Restore into Aurora

Console: Restore from S3 (or aws rds restore-db-cluster-from-s3 with --source-engine mysql --source-engine-version ... --s3-bucket-name ... --s3-ingestion-role-arn ...). Then add an instance to the cluster.

3. Replicate the delta

On Aurora (network path to the source required):

CALL mysql.rds_set_external_source_with_auto_position('src-mysql.example.com', 3306, 'repl', '<password>', 0);
-- or with file/position from xtrabackup_binlog_info:
-- CALL mysql.rds_set_external_source('src-mysql.example.com', 3306, 'repl', '<password>', 'binlog.004211', 1547, 0);
CALL mysql.rds_start_replication;
SHOW REPLICA STATUS\G

Procedure names differ between Aurora versions (rds_set_external_master on older ones). Check your version's documentation. Set binlog retention on the source long enough to cover the restore time.

Validation

  • Row counts/checksums on key tables (pt-table-checksum with the Aurora cluster as a replica).
  • Users and grants (not included in all paths). Recreate from SHOW GRANTS.
  • Parameters: create a DB cluster parameter group with settings like binlog_format (if Aurora must feed other consumers), time_zone, character_set_server.

Cut-over

  1. Stop writes on source; super_read_only = ON.
  2. Wait for lag 0 and equal GTID sets.
  3. CALL mysql.rds_stop_replication; CALL mysql.rds_reset_external_source;
  4. Point apps at the cluster endpoint; read-only traffic at the reader endpoint.
  5. Keep the source available read-only for rollback.

After go-live

  • Failover test: aws rds failover-db-cluster --db-cluster-identifier shop-aurora, and check app reconnect behaviour.
  • Consider RDS Proxy for apps with many short connections or slow failover handling.
  • Backtrack (if enabled at creation) for quick undo of logical mistakes; Performance Insights for query load.

Tip

Use a DNS CNAME you control (e.g. shop-db.internal) pointing at the cluster endpoint. Cut-over and any later move become a DNS change, not an app redeploy.

Checklist

  • Path chosen by source type and size
  • Backup/restore or replica lag measured in rehearsal
  • Binlog retention covers the catch-up window
  • Users, grants, parameters handled
  • Apps on cluster/reader endpoints; failover tested