Mysql Federation실험

MSA에서 DB의 Sync가 고민이 된다면.. Federation을 고민할 필요가 있다. mysql을 기준으로 Federation을 설정해 보고 DB간 안정성을 어떻게 담보하는지 실험해 보자.

환경설정

2개의 mysql docker container를 준비했다

  • mysql_docker_db_1 :
    • port : 3306
  • mysql_docker_db_2:
    • port : 3307

mysql_docker_db_1의 테이블에 mysql_docker_db_2테이블이 federation연결을 하여 Sync를 맞출 것이다.

mysql_docker_db_1

  • DB Name : cheuora_user
  • Table Name : EMPLOYEE
주석
ID varchar(32)  
EMP_NO varchar(50)  
BIRTHDAY varchar(32) NULL  

mysql_docker_db_2의 Federation설정

이제 지사 서버인 mysql_docker_db_2 를 설정한다. docker exec -it mysql_docker_db_2 /bin/bash 를 사용하여 컨테이너로 접속한 다음 mysql 터미널을 실행한다. 그리고 Federated설정이 YES로 되어 있는지 체크한다.

` mysql> show engines;`

이 때 FEDERATED가 NO로 되어 있으면 설정을 바꾸어 줘야 한다. 이 떄 my.cnf파일을 수정해야 하는데 컨테이너 내 bash에서는 텍스트 에디터가 없기 때문에 my.cnf를 컨테이너 밖에서 만든 다음 docker cp 를 사용해 복사해 준다.

my.cnf 파일

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html

[mysqld]
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql
# 추가된 부분!
federated  

pid-file=/var/run/mysqld/mysqld.pid
[client]
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/

저장 후에 docker cp로 이동시킨다.

> docker cp my.cnf mysql_docker_db_2:/etc/my.cnf

컨테이너를 restart시키면 cnf설정이 반영됨.

> docker restart mysql_docker_db_2

mysql_docker_db_2의 테이블 설정

이제 mysql_docker_db_2에서 mysql_docker_db_1의 EMPLOYEE에 federated된 테이블을 만들어 보자.

mysql> CREATE TABLE EMPLOYEE (
ID varchar(32) NOT NULL PRIMARY KEY,
EMP_NO varchar(50) NOT NULL,
BIRTHDAY varchar(32)
) ENGINE=FEDERATED Default Charset=utf8 
connection='mysql://[mysql_docker_db_1에서의 사용자ID]:[PASSWORD]@[mysql_docker_db_1이 위치한 IP]:3306/cheuora_user/EMPLOYEE';.

ENGINE=FEDERATED로 설정하고 connection 부분을 추가한 게 기존 테이블 생성과 좀 다른 부분이다.

그 외에는 본사 DB(mysql_docker_db_1)과 테이블 명 및 컬럼을 동일하게 맞춰야 한다.

mysql_docker_db_1 및 mysql_docker_db_2 에서 select, insert 테스트

mysql_docker_db_1 에 insert row를 하면 mysql_docker_db_2에 반영이 되어야 한다.

mysql_docker_db_1에 insert 해 보자

insert into EMPLOYEE
values ('emp001','kimsungjoon','19770110')

mysql_docker_db_2에서 select를 하면 반영이 된다.

mysql> select * from EMPLOYEE;
+--------+-------------+----------+
| ID     | EMP_NO      | BIRTHDAY |
+--------+-------------+----------+
| emp001 | kimsungjoon | 19770110 |
+--------+-------------+----------+
1 row in set (0.01 sec)

mysql_docker_db_2가 다운되면?

사실 본사 서버나 지사 서버가 다운될때 어떻게 될지가 제일 궁금했다. 지사 서버인 mysql_docker_db_2가 다운되면 어떻게 될 까?

본사 서버인 mysql_docker_db_1은 전혀 영향이 없이 정상 작동 한다. 만일 본사 서버에 업데이트가 일어난다면 mysql_docker_db_2가 재기동될 때 전부 자동으로 반영이 된다.

mysql_docker_db_1이 다운되면..?

본사 서버인 mysql_docker_db_1이 다운되면 mysql_docker_db_2에 영향이 미친다. select문 조차도 본사 서버와 connect를 하는 구조이기 때문에 select를 할 때 오류가 발생한다.

결론은 본사 서버가 다운되면 모든 지사 서버들에 영향을 미친다는 점이다.

DB 클러스터링과의 차이

만일 본사서버가 다운되어도 지사 서버가 계속 동작하기를 원한다면 Federation 보다는 클러스터링이 필요한데 이는 DB의 전문가 영역에서 다룰 부분이며 별도의 솔루션이 필요하다.

오픈소스계열의 Mysql 클러스터링 도구로는 https://galeracluster.com 이있다.

Federation주의사항

  • 같은 DB시스템 끼리여야 한다 : MYSQL
  • 같은 DB명 같은 TABLE명, 같은 컬럼 이어야 함.
  • 지사 DB에서 DDL(Data Definition Language)는 불가능함. DML(Data Manipulation Language)만 가능