본문 바로가기

Database/DB

2. mysql master - slave Replication

 

 

MySQL Master-Slave Replication 구성 및 테스트

이번 글에서는 Docker Compose를 이용해 MySQL Master-Slave 구조를 구성하고, 복제가 제대로 작동하는지 확인하는 방법을 소개한다.

1. docker-compose.yml 구성

version: '3.8'

services:
  master:
    image: mysql:5.7
    platform: linux/amd64   
    container_name: mysql-master
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - ./master/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./master/init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "3307:3306"

  slave:
    image: mysql:5.7
    platform: linux/amd64   
    container_name: mysql-slave
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - ./slave/my.cnf:/etc/mysql/conf.d/my.cnf
    depends_on:
      - master
    ports:
      - "3308:3306"

 

  • platform: linux/amd64 -> mysql:5.7 이미지는 ARM 아키텍처(macOS M1/M2 등)에서 작동하지 않기 때문에 설정을 추가
  • master와 slave 컨테이너는 각각 3307, 3308 포트를 통해 접근할 수 있다.
  • 초기 설정 및 복제 유저 생성은 master/init.sql에서 수행된다.
  • 설정 파일은 각각 my.cnf로 분리되어 server-id, log-bin 등의 복제 설정을 포함한다.

 

 

 

2. Master 상태 확인

docker exec -it mysql-master mysql -uroot -proot

 

 

이 명령어는 Master에서 현재 바이너리 로그 파일명(File)과 복제를 시작할 위치(Position)를 확인하는 데 사용된다.

binlog가 정상적으로 동작한느지 확인할 수 있다. 

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      154 | testdb       |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

 

 

 

 

3. Slave 복제 설정

docker exec -it mysql-slave mysql -uroot -proot

 

 

mysql> CHANGE MASTER TO
    ->   MASTER_HOST='mysql-master',
    ->   MASTER_USER='replica',
    ->   MASTER_PASSWORD='replica_pass',
    ->   MASTER_LOG_FILE='mysql-bin.000003',
    ->   MASTER_LOG_POS=154;
Query OK, 0 rows affected, 2 warnings (0.03 sec)

mysql> 
mysql> START SLAVE;

 

 

  • MASTER_HOST는 docker-compose 내 서비스 이름(mysql-master)을 그대로 사용한다.
  • MASTER_LOG_FILE, MASTER_LOG_POS는 앞서 Master에서 확인한 값을 입력한다.
  • MASTER_LOG_POS는 offset으로 master에서 확인한 현재 지점이 154로, 지금부터 복제하겠다는 뜻이 된다. (처음부터 복제한다면 0)

 

 

 

4. 복제 상태 확인

mysql> SHOW SLAVE STATUS;
+----------------------------------+--------------+-------------+-------------+---------------+------------------+---------------------+------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
| Slave_IO_State                   | Master_Host  | Master_User | Master_Port | Connect_Retry | Master_Log_File  | Read_Master_Log_Pos | Relay_Log_File   | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Master_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Master_SSL_Allowed | Master_SSL_CA_File | Master_SSL_CA_Path | Master_SSL_Cert | Master_SSL_Cipher | Master_SSL_Key | Seconds_Behind_Master | Master_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Master_Server_Id | Master_UUID                          | Master_Info_File           | SQL_Delay | SQL_Remaining_Delay | Slave_SQL_Running_State                                | Master_Retry_Count | Master_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Master_SSL_Crl | Master_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Master_TLS_Version |
+----------------------------------+--------------+-------------+-------------+---------------+------------------+---------------------+------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+
| Waiting for master to send event | mysql-master | replica     |        3306 |            60 | mysql-bin.000003 |                 154 | relay-log.000004 |           367 | mysql-bin.000003      | Yes              | Yes               |                 |                     |                    |                        |                         |                             |          0 |            |            0 |                 154 |            1559 | None            |                |             0 | No                 |                    |                    |                 |                   |                |                     0 | No                            |             0 |               |              0 |                |                             |                1 | 130f7fd1-743d-11f0-ad75-aa9c922af0ab | /var/lib/mysql/master.info |         0 |                NULL | Slave has read all relay log; waiting for more updates |              86400 |             |                         |                          |                |                    |                    |                   |             0 |                      |              |                    |
+----------------------------------+--------------+-------------+-------------+---------------+------------------+---------------------+------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+----------------------------+-----------+---------------------+--------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+

 

출력 결과에서 아래 두 항목이 모두 Yes여야 정상적으로 복제가 시작된 상태다.

Slave_IO_Running: Yes, Slave_SQL_Running: Yes 이면 복제 시작

 

이외에도 Slave_SQL_Running_State가 Slave has read all relay log; waiting for more updates처럼 나오는 경우, 현재 Master에서 더 이상 새로운 변경 사항이 없다는 의미다.

 

 

 

 


 

5. Master에 데이터 삽입

docker exec -it mysql-master mysql -uroot -proot
mysql> use testdb;
Database changed
mysql> CREATE TABLE users (
    ->   id INT AUTO_INCREMENT PRIMARY KEY,
    ->   name VARCHAR(100),
    ->   email VARCHAR(100)
    -> );
', 'alice@example.com');
INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com');

SELECT * FROM users;
Query OK, 0 rows affected (0.06 sec)

mysql> 
mysql> INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com');
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com');
Query OK, 1 row affected (0.00 sec)

mysql> 
mysql> SELECT * FROM users;
+----+-------+-------------------+
| id | name  | email             |
+----+-------+-------------------+
|  1 | Alice | alice@example.com |
|  2 | Bob   | bob@example.com   |
+----+-------+-------------------+
2 rows in set (0.01 sec)

 

  • users 테이블을 생성하고 데이터를 두 건 추가한다.
  • 추가한 결과 조회

 

 

 

 

 

6. Slave에서 복제된 데이터 확인

docker exec -it mysql-slave mysql -uroot -proot
mysql> use testdb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT * FROM users;
+----+-------+-------------------+
| id | name  | email             |
+----+-------+-------------------+
|  1 | Alice | alice@example.com |
|  2 | Bob   | bob@example.com   |
+----+-------+-------------------+
2 rows in set (0.01 sec)

 

  • Master에서 입력한 users 테이블의 데이터가 동일하게 Slave에서도 조회되어야 한다.
  • 복제가 성공적으로 수행 완료