MariaDB Replication
개인적으로 트랜잭션 처리가 중요할 경우에 noSQL 데이터베이스보다는 관계형 데이터베이스가 적합하다고 판단하며,
그 중에서도 저는 MariaDB가 비영리 목적으로 사용할 경우 무료로 사용할 수 있어 개인적인 용도로 많이 사용되고 있습니다.
Replication
은 복제라는 의미를 가지고 있으며,
Master와 Slave 구조로 데이터베이스 이중화 처리를 위해서 사용합니다.
Replication 원리
MariaDB에서는 INSERT, UPDATE, DELETE 문이 발생(데이터베이스에 수정)이 발생하였을 때,
Transaction에 관련한 부분을 Log파일로 관리하고 있으며 해당 Log파일을 통해서
서로 다른 MariaDB 서버가 비동기적으로 동기화를 진행합니다.
Master를 1개 지정하여 Write(쓰기)
만을 위한 권한을 주고,
Slave로 여러 대를 지정하여 Read(읽기)
만을 위한 권한을 주어,
Slow Query, Table Lock 과 같은 문제가 발생하였을 때 처리를 위해서
Master에서는 쓰기만, Slave에서는 읽기만 가능하도록 합니다.
왜 Docker 인가?
Docker는 이미지 기반으로 배포를 자유롭게 할 수 있으며, 쪼개어서 Container 단위로 관리가 가능하기 때문에,
Micro Architecture에 중요하게 작용하고 있습니다.
로컬에서 Vmware나 VirtualBox와 같은 OS단위의 가상화가 아닌 반가상화인 Docker를 통해 쉽고 빠르게 배포와 관리를 할 수 있습니다.
Docker가 설치가 되어있다는 전제하에 본 글을 진행하도록 하겠습니다.
Replication을 위한 MariaDB 설정 파일 생성
MariaDB의 설정 파일인 .cnf 파일을 통해서 설정합니다.
Docker/master/config.cnf
[mysqld]
log-bin=maria-bin
server-id=1
Docker/slave/config.cnf
[mysqld]
server-id=2
- log-bin
- Log파일 이름 지정
- server-id
- 서버 아이디 지정
Docker Network 생성
Docker에서는 Container간의 통신을 위해서 같은 Network에 소속되어 있어야 합니다.
$ docker network create replication
1fce7955cbd392f194ef2f249e6aa903ff6af360122327f454266221c10b5e7f
`
Docker Network 확인
추가한 replication이라는 Network가 잘 추가되었는지 확인합니다.
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
191a3bf2765f bridge bridge local
802c60718313 host host local
8ad318e255c1 none null local
1fce7955cbd3 replication bridge local
Docker Container 생성
Replication을 위한 MariaDB Master 컨테이너와 MariaDB Slave 컨테이너를 생성합니다.
maria-master
$ docker run --name maria-master --network replication -p 6000:3306 -v `pwd`/master/:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=지정할루트비밀번호 -d mariadb
a2d239ad61475398d533cbf8a3483262c757127ecf8905a67395cb33d47dc358
maria-slave
$ docker run --name maria-slave --network replication -p 6001:3306 -v `pwd`/slave/:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=지정할루트비밀번호 -d mariadb
f8bce6dba9f62e7069f080c6fc49fc97983fdd5cdb9d3b79912b56630bd13485
- --name
- Container 이름
- --network
- 컨테이너에 소속 시킬 네트워크 이름 (Master, Slave간의 통신을 위해)
- -p
- HostPort:ContainerPort (호스트 포트(로컬 포트)를 열어준다[포트포워딩])
- -v
- Host와 컨테이너의 파일 및 디렉토리 공유 (설정 파일 공유를 위해)
- -e
- 컨테이너에 환경변수 설정 (MariaDB 비밀번호 설정을 위해)
Docker Container 생성 확인
생성한 maria-master와 maria-slave가 생성이 잘 되었는지 확인합니다.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8bce6dba9f6 mariadb "docker-entrypoint.s…" Less than a second ago Up 52 seconds 0.0.0.0:6001->3306/tcp maria-slave
a2d239ad6147 mariadb "docker-entrypoint.s…" 17 seconds ago Up About a minute 0.0.0.0:6000->3306/tcp maria-master
MariaDB Replication
MariaDB Master 컨테이너에 Replication을 위한 사용자를 추가 해주어야 합니다.
$ docker exec -it maria-master bash
-it 옵션은 해당 컨테이너의 가상 TTY를 통해 접속한다는 의미를 가지고 있습니다.
해당 명령을 통해 maria-master 컨테이너에 bash shell을 사용하게 됩니다.
Replication 사용자 생성
Master 컨테이너에 Replication 권한을 가진 사용자를 생성합니다.
$ docker exec -it maria-master bash
root@a2d239ad6147:/# mysql -uroot -p루트비밀번호
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.2.14-MariaDB-10.2.14+maria~jessie-log mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create user 'repl'@'%' identified by '사용자비밀번호';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> grant replication slave on *.* to 'repl'@'%';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]>
Replication 사용자 접속 확인
Replication 권한을 가진 사용자가 접속이 잘되는지 확인해봅니다.
root@a2d239ad6147:/# mysql -urepl -p사용자비밀번호
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 10.2.14-MariaDB-10.2.14+maria~jessie-log mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> exit
Bye
테스트를 진행할 데이터베이스와 테이블 생성
Replication 설정 및 테스트를 위한 더미 데이터베이스와 테이블을 생성합니다.
root@a2d239ad6147:/# mysql -uroot -p루트비밀번호
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 10.2.14-MariaDB-10.2.14+maria~jessie-log mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create database repldb;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> use repldb;
Database changed
MariaDB [repldb]> create table user (user_name varchar(20));
Query OK, 0 rows affected (0.01 sec)
MariaDB [repldb]> desc user;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| user_name | varchar(20) | YES | | NULL | |
+-----------+-------------+------+-----+---------+-------+
1 row in set (0.00 sec)
데이터베이스 백업 파일 생성 및 복구
Replication을 위해서는 여러 데이터베이스가 동일한 정보를 가지고 있어야 하기에 해당 데이터베이스 파일을 백업합니다.
root@a2d239ad6147:/# mysqldump -uroot -p루트비밀번호 repldb > repldb.sql
MariaDB Slave 컨테이너에도 동일한 정보를 가지기 위해서 백업한 SQL파일을 옮깁니다.
$ docker cp maria-master:repldb.sql .
$ docker cp repldb.sql maria-slave:.
MariaDB Slave 컨테이너에 접속하여 백업받은 SQL파일을 복구시킵니다.
$ docker exec -it maria-slave bash
root@f8bce6dba9f6:/# mysql -uroot -p루트비밀번호
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.2.14-MariaDB-10.2.14+maria~jessie mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create database repldb;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> Bye
root@f8bce6dba9f6:/# mysql -uroot -p루트비밀번호 repldb < repldb.sql
root@f8bce6dba9f6:/# mysql -uroot -p루트비밀번호 repldb
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 10.2.14-MariaDB-10.2.14+maria~jessie mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [repldb]> desc user;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| user_name | varchar(20) | YES | | NULL | |
+-----------+-------------+------+-----+---------+-------+
1 row in set (0.00 sec)
생성했던 user테이블이 복구가 잘되었는지 확인합니다.
Master 컨테이너에서 Slave 컨테이너로 Replication을 진행하기 위해서
Slave 컨테이너가 Master 컨테이너의 Log파일의 이름과 위치를 알아야합니다.
그러므로 MariaDB Master 컨테이너에 접속하여 현재 Log파일의 이름과 위치정보를 알아옵니다.
$ docker exec -it maria-master bash
root@a2d239ad6147:/# mysql -uroot -p루트비밀번호
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 13
Server version: 10.2.14-MariaDB-10.2.14+maria~jessie-log mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show master status\G
*************************** 1\. row ***************************
File: maria-bin.000003
Position: 1068
Binlog_Do_DB:
Binlog_Ignore_DB:
1 row in set (0.00 sec)
현재 Master 컨테이너의 Log파일 이름은 maria-bin.000003 이며, 위치는 1068 인 것을 볼 수 있습니다.
MariaDB Slave 설정
마지막으로 MariaDB에 Slave를 설정합니다.
$ docker exec -it maria-slave bash
root@f8bce6dba9f6:/# mysql -uroot -p루트비밀번호
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 10.2.14-MariaDB-10.2.14+maria~jessie mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> change master to
-> master_host="maria-master",
-> master_user="repl",
-> master_password="사용자비밀번호",
-> master_log_file="maria-bin.000003",
-> master_log_pos=1068;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
조금전에 알아 왔던 MariaDB Master 컨테이너의 Log파일 이름과 위치를 입력합니다. MariaDB Slave 컨테이너의 마스터를 MariaDB Master 컨테이너로 설정해주고,
Slave 서버로 동작하도록 설정합니다.
MariaDB Slave 설정 확인
MariaDB Slave 컨테이너가 Slave 서버로 잘 동작하는지 확인합니다.
MariaDB [(none)]> show slave status\G
*************************** 1\. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: maria-master
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: maria-bin.000003
Read_Master_Log_Pos: 1068
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 555
Relay_Master_Log_File: maria-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1068
Relay_Log_Space: 865
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_SSL_Crl:
Master_SSL_Crlpath:
Using_Gtid: No
Gtid_IO_Pos:
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: conservative
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
1 row in set (0.00 sec)
해당 내용 중 Last_IO_Errno 부분에 0인 경우 Replication이 정상적으로 동작하는것을 의미합니다.
Replication Test
Replication이 정상적으로 동작하고 있는지 MariaDB Master 컨테이너에서 INSERT 쿼리를 통해서 데이터베이스에 변화를 줍니다.
$ docker exec -it maria-master bash
root@a2d239ad6147:/# mysql -uroot -p루트비밀번호 repldb
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 15
Server version: 10.2.14-MariaDB-10.2.14+maria~jessie-log mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [repldb]> insert into user (user_name) values ('admin');
Query OK, 1 row affected (0.01 sec)
MariaDB [repldb]> select * from user;
+-----------+
| user_name |
+-----------+
| admin |
+-----------+
1 row in set (0.00 sec)
MariaDB Master 컨테이너에서 정상적으로 데이터가 삽입된것을 확인했습니다.
$ docker exec -it maria-slave bash
root@f8bce6dba9f6:/# mysql -uroot -p루트비밀번호 repldb
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 16
Server version: 10.2.14-MariaDB-10.2.14+maria~jessie mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [repldb]> select * from user;
+-----------+
| user_name |
+-----------+
| admin |
+-----------+
1 row in set (0.00 sec)
MariaDB Slave 컨테이너에서도 정상적으로 데이터가 삽입되어져 있는 것을 확인 할 수 있었습니다.