<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vinit Parakh</title>
    <description>The latest articles on DEV Community by Vinit Parakh (@vinit_parakh_4ef28fb3b80f).</description>
    <link>https://dev.to/vinit_parakh_4ef28fb3b80f</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3193001%2F55384fe8-bd4b-49d0-8b70-c2a49c0ad697.jpg</url>
      <title>DEV Community: Vinit Parakh</title>
      <link>https://dev.to/vinit_parakh_4ef28fb3b80f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vinit_parakh_4ef28fb3b80f"/>
    <language>en</language>
    <item>
      <title>Zero-Downtime MySQL Migration to Aurora Using AWS DMS and Binlog Replication</title>
      <dc:creator>Vinit Parakh</dc:creator>
      <pubDate>Mon, 26 May 2025 21:11:18 +0000</pubDate>
      <link>https://dev.to/vinit_parakh_4ef28fb3b80f/zero-downtime-mysql-migration-to-aurora-using-aws-dms-and-binlog-replication-20mp</link>
      <guid>https://dev.to/vinit_parakh_4ef28fb3b80f/zero-downtime-mysql-migration-to-aurora-using-aws-dms-and-binlog-replication-20mp</guid>
      <description>&lt;h2&gt;
  
  
  Migrating MySQL to Amazon Aurora RDS: Backup, Restore, and Version Compatibility Guide
&lt;/h2&gt;

&lt;p&gt;Amazon Aurora offers high availability, scalability, and managed performance enhancements over traditional MySQL. Migrating your self-managed MySQL databases to Aurora can drastically simplify operations—but how you migrate depends on &lt;strong&gt;your MySQL version&lt;/strong&gt;, &lt;strong&gt;data size&lt;/strong&gt;, and &lt;strong&gt;constraints like foreign keys&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this guide, I’ll walk you through two proven backup-and-restore approaches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Percona XtraBackup for physical backup and streaming to Aurora&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mysqldump to Amazon S3 and restore to Aurora RDS&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And we’ll clarify &lt;strong&gt;when to use native restore&lt;/strong&gt;, and &lt;strong&gt;when to use AWS Database Migration Service (DMS)&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Method 1: Physical Backup using Percona XtraBackup (for large, same-version migrations)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Take a Physical Backup
&lt;/h3&gt;

&lt;p&gt;From the EC2 instance or the on-prem MySQL server, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;time &lt;/span&gt;xtrabackup &lt;span class="nt"&gt;--backup&lt;/span&gt; &lt;span class="nt"&gt;--slave-info&lt;/span&gt; &lt;span class="nt"&gt;--safe-slave-backup&lt;/span&gt; &lt;span class="nt"&gt;--stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;xbstream &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;--parallel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;6 &lt;span class="nt"&gt;--target-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/rack/240311-03603 2&amp;gt; /home/rack/240311-03603/xtrabackup_log &lt;span class="se"&gt;\&lt;/span&gt;
| pv &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-sb&lt;/span&gt; /san/mysql-fs/mysql/ | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
| zstd &lt;span class="nt"&gt;-3&lt;/span&gt; &lt;span class="nt"&gt;-T8&lt;/span&gt; | ssh user@destination_ip &lt;span class="s2"&gt;"zstd -d - | xbstream --parallel=3 -x -C /mysql_incoming"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Prepare the Backup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;xtrabackup &lt;span class="nt"&gt;--prepare&lt;/span&gt; &lt;span class="nt"&gt;--apply-log-only&lt;/span&gt; &lt;span class="nt"&gt;--target-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/mysql_incoming
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Upload to Amazon S3
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;cp&lt;/span&gt; /mysql_incoming s3://&amp;lt;bucket-name&amp;gt;/mysql_prepared/ &lt;span class="nt"&gt;--recursive&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Restore into Aurora
&lt;/h3&gt;

&lt;p&gt;Use the Aurora feature to &lt;strong&gt;restore from S3&lt;/strong&gt;, following:&lt;br&gt;
📖 &lt;a href="https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Migrating.ExtMySQL.S3.html" rel="noopener noreferrer"&gt;AWS Docs - Restore from S3 to Aurora MySQL&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  💡 When to Use Percona XtraBackup?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You are &lt;strong&gt;migrating from a MySQL version that's identical or Aurora-compatible&lt;/strong&gt; (e.g., MySQL 5.7.35 → Aurora MySQL 5.7)&lt;/li&gt;
&lt;li&gt;You want a &lt;strong&gt;faster and consistent snapshot&lt;/strong&gt; with binary log position (great for replication setup)&lt;/li&gt;
&lt;li&gt;You want to &lt;strong&gt;replicate to Aurora&lt;/strong&gt; after restoration for a phased cutover&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🛠️ Method 2: mysqldump and S3 Upload (for lighter or version-sensitive migrations)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Step 1: Export Schema
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqldump &lt;span class="nt"&gt;-h&lt;/span&gt; &amp;lt;source-endpoint&amp;gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;--no-data&lt;/span&gt; &lt;span class="nt"&gt;--set-gtid-purged&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;OFF mydb &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; schema.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 2: Upload to S3
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;schema.sql s3://&amp;lt;bucket-name&amp;gt;/schema/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 3: Restore into Aurora
&lt;/h3&gt;

&lt;p&gt;SSH into an EC2 or RDS-compatible shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-h&lt;/span&gt; &amp;lt;aurora-endpoint&amp;gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; &amp;lt; mydb &amp;lt; schema.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚠️ If MySQL Versions Don't Match: Use Staged Migration
&lt;/h2&gt;

&lt;p&gt;Let’s say your source is &lt;strong&gt;MySQL 5.7.36&lt;/strong&gt; and Aurora only supports up to &lt;strong&gt;5.7.35&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Restore the backup to an intermediate RDS MySQL instance&lt;/strong&gt; of same version (e.g., RDS MySQL 5.7.36)&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;AWS DMS&lt;/strong&gt; to migrate to Aurora (which supports MySQL 5.7.35 or compatible)&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;❗ DMS handles schema conversion and is ideal when you &lt;strong&gt;cannot do a physical restore&lt;/strong&gt; due to version mismatch or when &lt;strong&gt;foreign key constraints&lt;/strong&gt; exist.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔐 Handling DEFINERS in Procedures, Triggers, Functions, and Views
&lt;/h2&gt;

&lt;p&gt;When migrating MySQL databases to Amazon Aurora using tools like &lt;strong&gt;Percona XtraBackup&lt;/strong&gt; or &lt;strong&gt;mysqldump&lt;/strong&gt;, stored logic objects often retain a &lt;code&gt;DEFINER&lt;/code&gt; clause that references the original MySQL user.&lt;/p&gt;

&lt;p&gt;If the same user does not exist in Aurora or lacks necessary privileges, it can cause:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚠️ Import or replication failures&lt;/li&gt;
&lt;li&gt;❌ Application runtime errors&lt;/li&gt;
&lt;li&gt;🚩 Replication halts due to permission issues&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ Step 1: Identify DEFINERs on the Source MySQL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ROUTINE_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ROUTINE_TYPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;DEFINER&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;INFORMATION_SCHEMA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ROUTINES&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;ROUTINE_SCHEMA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'your_db'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;TRIGGER_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EVENT_OBJECT_TABLE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;DEFINER&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;INFORMATION_SCHEMA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TRIGGERS&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;TRIGGER_SCHEMA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'your_db'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;TABLE_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;DEFINER&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;INFORMATION_SCHEMA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VIEWS&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;TABLE_SCHEMA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'your_db'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  👥 Step 2: Recreate DEFINER Users in Aurora with Required Privileges
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'%'&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="s1"&gt;'StrongPassword123!'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;your_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;FLUSH&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the user doesn’t require login capabilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'admin'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'%'&lt;/span&gt; &lt;span class="n"&gt;ACCOUNT&lt;/span&gt; &lt;span class="k"&gt;LOCK&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✂️ Optional: Remove DEFINERs from Dumps
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqldump &lt;span class="nt"&gt;--routines&lt;/span&gt; &lt;span class="nt"&gt;--triggers&lt;/span&gt; &lt;span class="nt"&gt;--skip-definer&lt;/span&gt; &lt;span class="nt"&gt;--no-data&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; your_db &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; schema.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or manually remove them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt;.bak &lt;span class="s1"&gt;'s/DEFINER=[^*]*\*/\*/g'&lt;/span&gt; schema.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔍 Step 3: Post-Restore Validation in Aurora
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="k"&gt;PROCEDURE&lt;/span&gt; &lt;span class="n"&gt;STATUS&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;Db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'your_db'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;TRIGGERS&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;your_db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;TABLE_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;DEFINER&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;INFORMATION_SCHEMA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VIEWS&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;TABLE_SCHEMA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'your_db'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔁 Setting Up Replication from MySQL Source to Amazon Aurora
&lt;/h2&gt;

&lt;p&gt;To maintain &lt;strong&gt;real-time sync&lt;/strong&gt; between the source and the Aurora target until production cutover, follow these steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠️ Step 1: Enable Binary Logging on Source MySQL
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;my.cnf&lt;/code&gt; on the source server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[mysqld]&lt;/span&gt;
&lt;span class="py"&gt;server-id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1&lt;/span&gt;
&lt;span class="py"&gt;log-bin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;mysql-bin&lt;/span&gt;
&lt;span class="py"&gt;binlog_format&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;ROW&lt;/span&gt;
&lt;span class="py"&gt;binlog_row_image&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;FULL&lt;/span&gt;
&lt;span class="py"&gt;expire_logs_days&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;7&lt;/span&gt;
&lt;span class="py"&gt;sync_binlog&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart MySQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart mysqld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  👤 Step 2: Create Replication User on Source
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'repluser'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'%'&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="s1"&gt;'replpassword'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="n"&gt;REPLICATION&lt;/span&gt; &lt;span class="n"&gt;SLAVE&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'repluser'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;FLUSH&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📌 Step 3: Lock Tables and Get Replication Position
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;FLUSH&lt;/span&gt; &lt;span class="n"&gt;TABLES&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;READ&lt;/span&gt; &lt;span class="k"&gt;LOCK&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;MASTER&lt;/span&gt; &lt;span class="n"&gt;STATUS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the &lt;code&gt;File&lt;/code&gt; and &lt;code&gt;Position&lt;/code&gt;, e.g., &lt;code&gt;mysql-bin.000005&lt;/code&gt;, &lt;code&gt;1540&lt;/code&gt;. Keep session open until backup completes.&lt;/p&gt;

&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;UNLOCK&lt;/span&gt; &lt;span class="n"&gt;TABLES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ☁️ Step 4: Restore to Aurora (Already Done)
&lt;/h3&gt;

&lt;p&gt;Assume restore was done using same binlog position.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔗 Step 5: Configure External Replication in Aurora
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CALL&lt;/span&gt; &lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rds_set_external_master&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;host&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'source-mysql.example.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3306&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'repluser'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'replpassword'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;log_file&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'mysql-bin.000005'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;log_pos&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1540&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ssl&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ▶️ Step 6: Start Replication
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CALL&lt;/span&gt; &lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rds_start_replication&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔎 Step 7: Monitor Replication Status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;SLAVE&lt;/span&gt; &lt;span class="n"&gt;STATUS&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Slave_IO_Running: Yes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Slave_SQL_Running: Yes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Seconds_Behind_Master: 0&lt;/code&gt; (or minimal)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📊 Step 8: Monitor Replication Lag with CloudWatch
&lt;/h3&gt;

&lt;p&gt;Enable and alert on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AuroraReplicaLag&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReplicaLag&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use CloudWatch alarms if lag exceeds 30s.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚦 Step 9: Keep Replication Running Until Cutover
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Allow app writes to source until ready&lt;/li&gt;
&lt;li&gt;Stop writes during switchover&lt;/li&gt;
&lt;li&gt;Wait for &lt;code&gt;Seconds_Behind_Master = 0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Switch DNS (Route53) or promote Aurora:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws rds promote-read-replica-db-cluster &lt;span class="nt"&gt;--db-cluster-identifier&lt;/span&gt; your-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔐 Best Practices Before Replication or Cutover
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;binlog_format=ROW&lt;/code&gt; and &lt;code&gt;binlog_row_image=FULL&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;read_only=ON&lt;/code&gt; on the Aurora replica&lt;/li&gt;
&lt;li&gt;Adjust &lt;code&gt;innodb_buffer_pool_size&lt;/code&gt; based on source sizing&lt;/li&gt;
&lt;li&gt;Ensure &lt;strong&gt;all users and grants&lt;/strong&gt; are recreated in Aurora&lt;/li&gt;
&lt;li&gt;Pause replication before major changes; resume after sync&lt;/li&gt;
&lt;li&gt;Use CloudWatch to monitor &lt;code&gt;AuroraReplicaLag&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Test workloads in a &lt;strong&gt;non-prod clone&lt;/strong&gt; of Aurora before switching traffic&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛍️ Next Steps
&lt;/h2&gt;

&lt;p&gt;In my next post, I’ll walk you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating DMS source and target endpoints&lt;/li&gt;
&lt;li&gt;Setting up AWS DMS replication tasks&lt;/li&gt;
&lt;li&gt;Handling view tables, user permissions, and Route 53 cutover&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned!&lt;/p&gt;

</description>
      <category>awsdms</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
