<?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: Fred Dowson</title>
    <description>The latest articles on DEV Community by Fred Dowson (@freddowson).</description>
    <link>https://dev.to/freddowson</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%2F3775933%2F865cc784-4b33-44da-82e9-5b51818b3f36.png</url>
      <title>DEV Community: Fred Dowson</title>
      <link>https://dev.to/freddowson</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/freddowson"/>
    <language>en</language>
    <item>
      <title>MySQL replication setup — 6 steps to configure master-slave replication</title>
      <dc:creator>Fred Dowson</dc:creator>
      <pubDate>Mon, 16 Feb 2026 14:51:05 +0000</pubDate>
      <link>https://dev.to/freddowson/mysql-replication-setup-6-steps-to-configure-master-slave-replication-1epn</link>
      <guid>https://dev.to/freddowson/mysql-replication-setup-6-steps-to-configure-master-slave-replication-1epn</guid>
      <description>&lt;p&gt;MySQL replication is a process where data from one database server (master) is copied automatically to one or more database servers (slaves). This creates redundancy and allows you to distribute read operations across multiple servers.&lt;/p&gt;

&lt;p&gt;Setting up replication might seem complex, but the process is actually straightforward. It takes about 15-20 minutes to configure a basic master-slave setup. The key steps involve configuring both servers, creating a replication user, and telling the slave where to read data from.&lt;/p&gt;

&lt;p&gt;This guide walks through a real-world replication setup. We'll use MySQL 8.0, but these steps work for MySQL 5.7 and MariaDB as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ufr4y21qek75avt8sgl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ufr4y21qek75avt8sgl.png" alt="MySQL replication" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use MySQL replication
&lt;/h2&gt;

&lt;p&gt;Replication solves several practical problems. You get automatic data redundancy without manually copying databases. Read operations can be distributed to slave servers, reducing load on the master. And if your master server fails, you can promote a slave to take over.&lt;/p&gt;

&lt;p&gt;The performance benefits are real. A single master handling all reads and writes will eventually hit limits. With replication, you can send all writes to the master and distribute reads across multiple slaves. Some applications see 60-70% load reduction on the master server just from this split.&lt;/p&gt;

&lt;p&gt;Replication is not the same as backups though. If someone accidentally deletes a table on the master, that deletion will replicate to all slaves within seconds. You still need proper &lt;a href="https://databasus.com/mysql-backup" rel="noopener noreferrer"&gt;MySQL backup&lt;/a&gt; for actual data protection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites for setting up replication
&lt;/h2&gt;

&lt;p&gt;You need two MySQL servers. They can be physical servers, VMs, or Docker containers. Both servers should run the same MySQL version or at least compatible versions. Mixing MySQL 5.7 and 8.0 works, but stay within the same major version when possible.&lt;/p&gt;

&lt;p&gt;Network connectivity between servers is critical. The slave must be able to reach the master on MySQL's port (usually 3306). If you're using cloud servers, check security groups and firewall rules. Test connectivity with &lt;code&gt;telnet master-ip 3306&lt;/code&gt; before starting.&lt;/p&gt;

&lt;p&gt;You'll also need root access to both MySQL instances. Replication requires changing configuration files and creating users with specific privileges. Make sure you can edit &lt;code&gt;/etc/mysql/my.cnf&lt;/code&gt; or equivalent on both servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Configure the master server
&lt;/h2&gt;

&lt;p&gt;Open the MySQL configuration file on your master server. On Ubuntu/Debian, this is usually &lt;code&gt;/etc/mysql/mysql.conf.d/mysqld.cnf&lt;/code&gt;. On CentOS/RHEL, check &lt;code&gt;/etc/my.cnf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Add these lines under the &lt;code&gt;[mysqld]&lt;/code&gt; section:&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;/var/log/mysql/mysql-bin.log&lt;/span&gt;
&lt;span class="py"&gt;binlog_do_db&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;production_db&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;server-id&lt;/code&gt; must be unique across all servers in your replication setup. Use 1 for the master, 2 for the first slave, and so on. The &lt;code&gt;log_bin&lt;/code&gt; parameter tells MySQL where to store binary logs. These logs contain all changes made to the database. The slave reads these logs to replicate changes.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;binlog_do_db&lt;/code&gt; parameter is optional but recommended. It limits replication to specific databases. If you want to replicate all databases, remove this line. If you have multiple databases to replicate, add multiple &lt;code&gt;binlog_do_db&lt;/code&gt; lines.&lt;/p&gt;

&lt;p&gt;Restart MySQL to apply changes:&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 mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the binary log is working by logging into MySQL and running:&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;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;You should see output showing the binary log file name and position. If you see an error, check the MySQL error log at &lt;code&gt;/var/log/mysql/error.log&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create a replication user
&lt;/h2&gt;

&lt;p&gt;The slave needs credentials to connect to the master. Create a dedicated user with replication privileges. Log into the master MySQL server:&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;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the replication user:&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;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'replica_user'&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;'strong_password_here'&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;'replica_user'&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;The &lt;code&gt;'%'&lt;/code&gt; means this user can connect from any IP address. In production, replace &lt;code&gt;%&lt;/code&gt; with the slave server's specific IP for better security. For example, &lt;code&gt;'replica_user'@'192.168.1.50'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The password should be strong. Replication traffic is not encrypted by default, so anyone with network access could potentially intercept it. You can enable SSL for replication, but that's beyond basic setup.&lt;/p&gt;

&lt;p&gt;Keep these credentials handy. You'll need them in step 4 when configuring the slave.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Get the master position and create initial backup
&lt;/h2&gt;

&lt;p&gt;Before setting up the slave, you need to capture the exact position in the binary log where replication should start. You also need a copy of the master's data.&lt;/p&gt;

&lt;p&gt;Lock the master database to prevent changes:&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents any writes to the database. Your application will still be able to read data, but writes will block. Work quickly through the next steps.&lt;/p&gt;

&lt;p&gt;Get the current binary log position:&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;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;Write down the &lt;code&gt;File&lt;/code&gt; and &lt;code&gt;Position&lt;/code&gt; values. You'll need these exact values later. They look something like &lt;code&gt;mysql-bin.000003&lt;/code&gt; and &lt;code&gt;157&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now create a backup of your database. Open another terminal session (don't close the MySQL session with the lock) and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysqldump &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; production_db &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; master_backup.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait for the dump to complete. The time depends on your database size. Once finished, go back to your MySQL session and unlock the tables:&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;p&gt;Your master is now free to accept writes again. Transfer the backup file to your slave server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp master_backup.sql user@slave-server:/tmp/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Configure the slave server
&lt;/h2&gt;

&lt;p&gt;The slave configuration is similar to the master. Edit the MySQL configuration file on the slave server and add these lines:&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;2&lt;/span&gt;
&lt;span class="py"&gt;relay-log&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;/var/log/mysql/mysql-relay-bin&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;/var/log/mysql/mysql-bin.log&lt;/span&gt;
&lt;span class="py"&gt;binlog_do_db&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;production_db&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;server-id&lt;/code&gt; must be different from the master. Use 2 for your first slave. The &lt;code&gt;relay-log&lt;/code&gt; parameter specifies where the slave stores logs received from the master. The slave processes these relay logs to apply changes.&lt;/p&gt;

&lt;p&gt;Including &lt;code&gt;log_bin&lt;/code&gt; on the slave is optional but useful. If you ever need to chain replication (slave of a slave), you'll need binary logs enabled. It also helps with backup tools that read binary logs.&lt;/p&gt;

&lt;p&gt;Restart the slave MySQL server:&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 mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import the backup you transferred earlier:&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;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; production_db &amp;lt; /tmp/master_backup.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures the slave starts with the exact same data as the master had at the moment you locked tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Start replication
&lt;/h2&gt;

&lt;p&gt;Log into the slave MySQL server and tell it where to replicate from. Use the master position you wrote down in step 3:&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;STOP&lt;/span&gt; &lt;span class="n"&gt;SLAVE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;CHANGE&lt;/span&gt; &lt;span class="n"&gt;MASTER&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt;
  &lt;span class="n"&gt;MASTER_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'master-ip-address'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;MASTER_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'replica_user'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;MASTER_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'strong_password_here'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;MASTER_LOG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'mysql-bin.000003'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;MASTER_LOG_POS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;157&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;START&lt;/span&gt; &lt;span class="n"&gt;SLAVE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;master-ip-address&lt;/code&gt; with your master server's IP. Use the exact &lt;code&gt;MASTER_LOG_FILE&lt;/code&gt; and &lt;code&gt;MASTER_LOG_POS&lt;/code&gt; values from step 3. Getting these wrong means the slave won't know where to start reading.&lt;/p&gt;

&lt;p&gt;Check if replication is working:&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;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;Look for these two lines in the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Slave_IO_Running: Yes
Slave_SQL_Running: Yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both must say "Yes". If either says "No" or "Connecting", something went wrong. Check the error messages in the same output. Common issues include wrong credentials, network connectivity problems, or incorrect log positions.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Seconds_Behind_Master&lt;/code&gt; value shows replication lag. Zero means the slave is caught up. A few seconds is normal. If this number keeps growing, the slave can't keep up with the master's write load.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Test the replication
&lt;/h2&gt;

&lt;p&gt;Create a test table on the master to verify replication works. Log into the master MySQL:&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;USE&lt;/span&gt; &lt;span class="n"&gt;production_db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;replication_test&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;replication_test&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Replication is working'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now check the slave. Log into the slave MySQL and run:&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;USE&lt;/span&gt; &lt;span class="n"&gt;production_db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;replication_test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the same data. The table and row should appear on the slave within seconds. If you don't see it, replication is not working properly. Go back and check the slave status with &lt;code&gt;SHOW SLAVE STATUS\G&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Try updating and deleting rows on the master. All changes should replicate to the slave. But remember: never write data directly to the slave. The slave should be read-only except for replication. You can enforce this by adding &lt;code&gt;read_only=1&lt;/code&gt; to the slave's MySQL configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common replication issues
&lt;/h2&gt;

&lt;p&gt;The most frequent problem is replication stopping after a while. This usually happens when a query succeeds on the master but fails on the slave. For example, if you have a unique key constraint and somehow the same value gets inserted twice (maybe from manual changes to the slave).&lt;/p&gt;

&lt;p&gt;When replication stops, &lt;code&gt;SHOW SLAVE STATUS\G&lt;/code&gt; will show an error message. Read it carefully. It tells you exactly what query failed and why. Sometimes you can skip the problematic query:&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;STOP&lt;/span&gt; &lt;span class="n"&gt;SLAVE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;GLOBAL&lt;/span&gt; &lt;span class="n"&gt;SQL_SLAVE_SKIP_COUNTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;START&lt;/span&gt; &lt;span class="n"&gt;SLAVE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This skips one event from the master. Use it carefully because you're intentionally making the slave different from the master. Only skip events if you understand why the error happened and know skipping won't cause data inconsistency.&lt;/p&gt;

&lt;p&gt;Another common issue is replication lag. The slave falls behind because it can't process changes fast enough. This happens when the master has high write load. The slave processes changes sequentially by default, while the master uses multiple threads.&lt;/p&gt;

&lt;p&gt;MySQL 8.0 supports parallel replication which helps a lot. Enable it on the slave:&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;STOP&lt;/span&gt; &lt;span class="n"&gt;SLAVE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;GLOBAL&lt;/span&gt; &lt;span class="n"&gt;slave_parallel_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'LOGICAL_CLOCK'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;GLOBAL&lt;/span&gt; &lt;span class="n"&gt;slave_parallel_workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;START&lt;/span&gt; &lt;span class="n"&gt;SLAVE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the slave to use 4 threads for applying changes. Adjust the number based on your slave server's CPU cores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Replication vs backups
&lt;/h2&gt;

&lt;p&gt;Here's something important to understand: replication is not a backup solution. New MySQL administrators often confuse the two. Replication creates live copies of your data, but if you accidentally drop a table on the master, that drop command replicates instantly to all slaves.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Replication&lt;/th&gt;
&lt;th&gt;Backups&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Purpose&lt;/td&gt;
&lt;td&gt;High availability and read scaling&lt;/td&gt;
&lt;td&gt;Data protection and recovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recovery point&lt;/td&gt;
&lt;td&gt;Current state only&lt;/td&gt;
&lt;td&gt;Historical points in time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accidental deletions&lt;/td&gt;
&lt;td&gt;Replicated to slaves&lt;/td&gt;
&lt;td&gt;Can be restored from backup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hardware failure&lt;/td&gt;
&lt;td&gt;Switch to slave in seconds&lt;/td&gt;
&lt;td&gt;Restore from backup (minutes to hours)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Corruption protection&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You need both. Use replication for availability and performance. Use proper backups for actual data protection. Databasus handles MySQL backups with scheduled dumps, compression and storage to S3 or other locations. It's an industry standard for MySQL backup tools and works alongside replication without issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring replication health
&lt;/h2&gt;

&lt;p&gt;Set up monitoring for replication status. At minimum, check these metrics every few minutes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Slave_IO_Running&lt;/code&gt; and &lt;code&gt;Slave_SQL_Running&lt;/code&gt; must be "Yes"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Seconds_Behind_Master&lt;/code&gt; should stay low (under 10 seconds for most applications)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Last_Error&lt;/code&gt; should be empty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write a simple monitoring script:&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="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;SLAVE_STATUS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SHOW SLAVE STATUS&lt;/span&gt;&lt;span class="se"&gt;\G&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nv"&gt;IO_RUNNING&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SLAVE_STATUS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Slave_IO_Running:"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;SQL_RUNNING&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SLAVE_STATUS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Slave_SQL_Running:"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;SECONDS_BEHIND&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SLAVE_STATUS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Seconds_Behind_Master:"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IO_RUNNING&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"Yes"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SQL_RUNNING&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"Yes"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ALERT: Replication stopped"&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi

if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SECONDS_BEHIND&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 60 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"WARNING: Replication lag is &lt;/span&gt;&lt;span class="nv"&gt;$SECONDS_BEHIND&lt;/span&gt;&lt;span class="s2"&gt; seconds"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this script via cron every 5 minutes. Send alerts to your monitoring system or just email them. You need to know immediately if replication breaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling beyond one slave
&lt;/h2&gt;

&lt;p&gt;Once you have one slave working, adding more is easy. Each additional slave follows the same process. Just remember to use a unique &lt;code&gt;server-id&lt;/code&gt; for each slave.&lt;/p&gt;

&lt;p&gt;Some applications use multiple slaves for different purposes. One slave handles reporting queries that run for minutes. Another slave serves read traffic from the application. This prevents slow queries from affecting application performance.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Slave type&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Read replica&lt;/td&gt;
&lt;td&gt;Handles application read queries&lt;/td&gt;
&lt;td&gt;Standard configuration, parallel replication enabled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reporting slave&lt;/td&gt;
&lt;td&gt;Runs long analytics queries&lt;/td&gt;
&lt;td&gt;Lower priority, larger query cache&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backup slave&lt;/td&gt;
&lt;td&gt;Dedicated for taking backups&lt;/td&gt;
&lt;td&gt;Delays replication during backup window&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can also set up a delayed slave. This slave runs a few hours behind the master on purpose. If someone accidentally deletes data, you have a few hours to stop the delayed slave before the deletion replicates. Configure it with &lt;code&gt;CHANGE MASTER TO MASTER_DELAY = 10800&lt;/code&gt; (3 hours in seconds).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;MySQL replication setup takes about 20 minutes once you know the steps. Configure the master to enable binary logging, create a replication user, capture the log position, set up the slave configuration, start replication and verify it works.&lt;/p&gt;

&lt;p&gt;The most common mistakes are using the wrong binary log position or having network connectivity issues. Take your time with step 3 and double-check the position values. Monitor your replication setup actively.&lt;/p&gt;

&lt;p&gt;And remember: replication provides high availability and read scaling, but it doesn't replace backups. Use both together for a robust database infrastructure.&lt;/p&gt;

</description>
      <category>database</category>
      <category>opensource</category>
      <category>mysql</category>
    </item>
  </channel>
</rss>
