DB Replication의 이해
Replication 이란?
DB 복제를 의미한다. 2개 이상의 DBMS를 Master와 Slave로 나누어, Master 에 저장된 데이터를 Slave에 복사하는 방식이다.
Replication을 하는 이유
실시간 데이터 백업이 가능하다.
DB 서버 부하 분산이 가능하다. (Master에서는 주로 insert, delete, update / Slave에서는 주로 select)
Master DB가 작동하지 않을 때, Slave DB로 변환하여 서비스를 유지할 수 있다.
Master와 Slave의 역할
master: 데이터 변경 시 binary logs에 기록하고 slave 서버에 전달한다. master는 slave에 대한 정보를 전혀 모른다 (몇 개의 slave가 있는지 등)
slave: master에서 전달받은 binary log를 읽어 DB에 반영한다.
binary log 란?
DB에서 발생하는 모든 내역들이 기록되는 파일이다. binlog라고도 불린다. default는 비활성되어있는데, 이를 활성화시켜야 한다.
Replication 동작 과정
DB 이용자는 insert, update, delete 등으로 데이터 변경을 요청한다.
Master는 Binary Log에 변경사항을 기록한다.
Connection thread는 스토리지 엔진에게 Commit을 수행한다.
Slave가 I/O thread를 통해 Master에게 Event 요청 시 Master의 Binary log dump thread(Master thread)를 통해 Binary log를 전송한다.
Slave는 전송받은 파일을 Relay Log에 기록한다.
Slaves는 SQL thread를 통해 스토리지 엔진에 변경 사항을 기록한다.
주의사항
Replication전에 Master와 Slave의 데이터를 통일시킨다.
Slave는 Master 보다 MariaDB가 동일 or 상위 버전이어야 한다.
Master → Slave 순으로 작동시켜야 한다.
Replication을 하다 보면 binary log가 계속 쌓인다. 이때는 my.ini 파일에 expire_logs_days = 숫자 로 유효기간을 지정한다.
Replication 과정에서 에러가 발생하는 경우, slave는 에러 로그를 작성한다. 후에 에러를 보고 유실된 자료에 대해 자동 업데이트가 가능하다.
Replication 실습
Master PC 설정
C:\Program Files\MariaDB 10.4\data 경로로 이동하여 my.ini를 열고 아래 3줄을 추가한다.
[mysqld]
...
log-bin = mysql-bin
server-id = 1
expire_logs_days = 2
mysql-bin: binary log의 파일명을 의미한다.
server-id: master와 slave의 값만 다르면 된다. 아무 숫자나 사용 가능.
expire_logs_days: 보관기간을 설정한다.
MariaDB 접속
윈도우에서 MySQL Client(Maria DB) 를 실행시키고 비밀번호를 입력하여 MariaDB에 접속한다.
slave에서 접속할 계정생성
MariaDB [(none)]> grant replication slave on . to '아이디'@'%' identified by '비밀번호';
Server-id 확인 및 수동설정
MariaDB [(none)]> set global server_id = 1;
Query OK, 1 rows affected (0.000 sec)
MariaDB [(none)]> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 1 |
+---------------+-------+
1 row in set (0.001 sec)
binary log 확인
show master status;
File 명과 Position을 잘 기록해둔다. DB 재시작 시 file명과 position 번호가 변경될 수 있다.
Slave PC 설정
C:\Program Files\MariaDB 10.4\data 경로로 이동하여 my.ini를 열고 아래 정보를 추가한다.
[mysqld]
...
log-bin = mysql-bin
server-id = 2
MariaDB 접속
윈도우에서 MySQL Client(Maria DB) 를 실행시키고 비밀번호를 입력하여 MariaDB에 접속한다.
Server-id 확인 및 수동설정
MariaDB [(none)]> set global server_id = 2;
Query OK, 1 rows affected (0.000 sec)
MariaDB [(none)]> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 2 |
+---------------+-------+
1 row in set (0.001 sec)
Master 와 연결
MariaDB [(none)]> Change master to
-> MASTER_HOST='마스터 아이피',
-> MASTER_USER='마스터 아이디',
-> MASTER_PASSWORD='마스터 비밀번호',
-> MASTER_PORT=마스터 포트번호,
-> MASTER_LOG_FILE='아까 확인한 file 이름',
-> MASTER_LOG_POS=아까 확인한 Position 숫자;
slave 실행
MariaDB [(none)]> start slave;
slave 상태 확인
MariaDB [(none)]> show slave status \G;
Slave_IO_Running, Slave_SQL_Running 가 모두 YES이고 Slave_SQL_Running_State가 waiting for the slave I/O thread to update it 이면 정상동작이다.
slave 종료
MariaDB [(none)]> stop slave;
을 하게되면 실시간 복제가 중지된다.
Replication 문제대응
MariaDB [(none)]> show slave status \G; 를 검색했을 때 Slave_IO_Running or Slave_SQL_Running 중 하나라도 No라면 Replication이 동작하지 않는 것이다.
원인은 정말 다양하기에 Last_Errno, Last_Error 을 확인한 후 검색하며 해결하면 되지만, 그동안 우리회사에서 발생한 사례와 해결방안을 공유한다. 문제에 대부분은 Master와 Slave의 Sync가 맞지 않아 발생한다. 하여 Sync를 맞추는 것을 목표로 한다.
Master GoWIX 업데이트 후 Slave에서 Slave_SQL_Running 값이 No가 되었다. 로그를 확인해보니
[ERROR] Slave SQL: Error ''cdss.worklist_view' is not of type 'VIEW'' on query. Default database: 'cdss'.
이러한 메세지가 나왔고 view 테이블의 경우는 Replication 하지 않아도 되는 테이블이기에
stop slave;
set global_sql_slave_skip_counter=1;
start slave;
를 입력한 후 다시 확인했더니 Slave_SQL_Running 값이 Yes가 되었다.
set global_sql_slave_skip_counter 명령어는 에러난 SQL을 얼마나 무시하고 계속 진행할지 정하는 명령어이고 숫자는 SQL 갯수를 의미한다.
Slave PC를 재부팅 했는데 MariaDB가 실행되지 않는 문제가 생겼다. 재실행해도 강제로 중지되었다. 에러로그를 확인해보니
[ERROR] C:\Program Files\MariaDB 10.4\bin\mysqld.exe: unknown variable 'MASTER_HOST=172.16.1.103"'
[ERROR] Aborting
이러한 메세지가 나왔고 my.ini파일에서 Master에 정보를 모두 삭제하고 재실행하니 동작하였다.
그런데 추가적으로 Sync가 맞지 않았다. Slave_SQL_Running 값이 No였다.
SHOW MASTER STATUS\G;
SHOW SLAVE STATUS\G;
검색하여 확인해보니 File 과 Position 번호가 달라진 것을 확인했다. 하여 Slave에서
change master to
master_log_file='mariadb-bin.번호',
master_log_pos=번호';
로 Master와 Sync를 맞춰주었더니 Yes로 변경되었다.