Skip to main content

Command Palette

Search for a command to run...

MySQL data persistence hosted on two separate EC2 intances using Elastic Block Storage (EBS)

Updated
4 min read

Docker containers, by design, are ephemeral. This means that any data generated inside a container will be lost when the container stops or is deleted. For applications like MySQL, where data persistence is crucial, this default behavior can be problematic.

To ensure that MySQL data remains intact even if a container is removed, Docker provides a mechanism known as "volumes". Docker volumes allow data to be stored outside the container on the host system. By mounting a Docker volume to the required directory inside the container (e.g., /var/lib/mysql for MySQL), any data written to that directory will be saved on the volume and not inside the ephemeral container.

However, using Docker volumes on AWS EC2 instances presents another challenge. If the underlying EC2 instance experiences corruption or any other issue, all data, including Docker volumes on that instance, might be at risk.

To address this potential point of failure, Amazon Elastic Block Store (EBS) can be utilized. EBS provides block-level storage volumes that can be attached to EC2 instances and are ideal for databases like MySQL. By creating an additional EBS disk and mounting the host volume (where the Docker volume data is saved) to this EBS disk, we add an extra layer of durability to our setup.

If the EC2 instance faces any problems, the beauty of EBS is its detachability. One can easily detach the EBS volume from the corrupted instance and attach it to a new EC2 instance. This ensures that your MySQL data remains intact, without any need for data migration or restoration from backups.

In this blog post, I'll demonstrate data persistence between two different MySQL databases hosted on two separate EC2 instances using Elastic Block Storage (EBS).

Prerequisites

  • In the navigation pane, choose Volumes under Elastic Block Store.

  • Click Create Volume.

    • Choose the type of volume you want to create. General purpose SSD (gp2 or gp3) is a good default choice for many workloads.

    • Set the size of the volume.

    • For Availability Zone, choose the same zone as your EC2 instance. This is important because volumes can only be attached to instances in the same zone.

    • Click Create.

  • After the volume is created, select it, click on the Actions button, and then choose Attach Volume.

  • In the Attach Volume dialog box:

    • For Instance, start typing the name or ID of the instance, and then select Instance-1 from the list.

    • For Device, enter a device name. The name will depend on your instance type and the OS. For example, /dev/sdf (for instances launched using a classic block device mapping) or /dev/nvme1n1 (for Nitro-based instances).

    • Click Attach.

Setting Up on the First EC2 Instance

  • SSH into the first EC2 instance and run the below command:

      sudo apt update
      sudo apt install docker.io docker-compose -y
    
  • Clone docker-compose file and create a directory data

      git clone https://github.com/linckon/mysql-db-data-persistence.git
      cd mysql-db-data-persistence
      mkdir data
    
  • Check if the disk is visible using:

       sudo lsblk
    

  • Identify the new disk. It might be listed as nvme1n1, xvdf, or something similar, depending on your instance type and how many disks are attached:

       sudo file -s /dev/xvdf
    
  • Format the disk (assuming it's a new volume and you're not trying to preserve any data on it). For example, to format it with the ext4 filesystem:

      sudo mkfs -t xfs /dev/xvdf
    

  • Mount the EBS volume to a directory, for example /data:

      sudo mount /dev/xvdf /home/ubuntu/mysql-db-data-persistence/data
    

  • Navigate to the directory containing the docker-compose.yml file.

  • Run the Docker Compose command:

      docker-compose up -d
    
  • Login to mysql inside docker container and create a table called person inside database db and insert some sample data:

      docker exec -it db bash
    

Better Resolution

  • Now MySQL data persists into an additional disk, if the instance is corrupted we can simply detach the disk and attach it will another instance.

  • Detach the EBS volume from this instance and attach it to the second EC2 instance .

Setting Up on the Second EC2 Instance

  • SSH into the second EC2 instance and run the below command:

      sudo apt update
      sudo apt install docker.io docker-compose -y
    
  • Clone docker compose file and create a directory data

      git clone https://github.com/linckon/mysql-db-data-persistence.git
      cd mysql-db-data-persistence
      mkdir data
    
  • Mount the EBS volume:

      sudo mount /dev/xvdf /home/ubuntu/mysql-db-data-persistence/data
    

  • Navigate to the directory containing the docker-compose.yml file.

  • Run the Docker Compose command:

      docker-compose up -d
    
  • login to mysql inside docker container and run:

    Better Resolution

    Better Resolution

All data should remain the same as Instance-1.

Github Link