Replication
GTID란?
- 5.6 버전까지 GTID를 사용하기 위해서는 복제 그룹의 모든 DB가 log-bin, log-slave-updates 옵션을 사용해야 한다.
- GTID 컨셉은, '누구나 Master가 될 수 있다'라는 것이다.
- 5.7 버전부터는 log-bin, log-slave-updates 옵션의 사용이 필수가 아니지만, master 역할을 부여받을 가능성이 있는 DB는 반드시 log-bin, log-slave-updates 옵션을 켜야 한다.
개념
- GTID
- GTID Set
- Executed GTID
- 초기화 된 후 실행된 GTID set. gtid_executed 시스템 변수에서 확인 가능함.
- Master 입장에서는 자신의 GTID 발급 현황을, Slave 입장에서는 Master의 트랜잭션이 어디까지 반영되었는지 의미.
> SHOW GLOBAL VARIABLES LIKE 'gtid_executed';
- Purged GTID
slave에서 GTID set이 유실된 경우, 그리고 master에서도 purge되고 남아있지 않은 경우:
- Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.
누락된 트랜잭션을 Empty 트랜잭션으로 Skip 처리하거나:
slave> STOP SLAVE SQL_THREAD;
slave> SET GTID_NEXT='9d850d65-219f-11e6-b652-08002702c825:113';
slave> BEGIN; COMMIT;
slave> SET GTID_NEXT='AUTOMATIC';
slave> START SLAVE SQL_THREAD;
또는 slave의 gtid_executed 값을 적절히 변경
slave> STOP SLAVE SQL_THREAD;
slave> SHOW GLOBAL VARIABLES LIKE 'gtid_executed';
-> 9d850d65-219f-11e6-b652-08002702c825:285 ...
slave > RESET MASTER;
slave> SET GLOBAL GTID_PURGED=9d850d65-219f-11e6-b652-08002702c825:1-285;
slave> START SLAVE SQL_THREAD;
GTID_EXECUTED 시스템 변수는 READ ONLY이다. 따라서 GTID_PURGED를 활용한다. RESET MASTER를 하면 GTID가 초기화된다.
mysql> RESET MASTER;
mysql> SET GLOBAL GTID_PURGED='9d850d65-219f-11e6-b652-08002702c825:1-2000;
MMM
replication에 관련한 생활코딩 강의가 있네.
Multi-Master Replication Manager for MySQL (mmm). MySQL의 replication monitoring manager tool.
mmm 도구가 좋아보이기는 하는데, 이렇게 제대로 사용하려면 DB용 서버가 따로 있어야 할 것 같다. 지금 리트머스 구성은 switch 1대, server1, server2 이렇게인데, 원래 제안했던대로 switch, webserver1, webserver2, db1, db2 이렇게 구성되어야 mmm에 어울리는 구성인 것 같다. mmm은 IP를 switch하는 방식으로 동작한다고 하니.
Digital Ocean 글
How to Setup MySQL Master-Master Replication: deprecated method. but would still work.
Group Replication 방식이 더 선호되는 것 같다. 하지만 ansible script로 간단히 구축될 것 같아보이지 않는다.
Trial
리트머스 설치 직후 slave의 GTID가 이상이 있다는 문제는, RESET MASTER를 하면 쉽게 해결되었다.
하지만, 여전히 slave에서 변경(UPDATE)을 가한 뒤에는 sync할 GTID를 master에서 찾지 못했다는 오류가 발생한다. master-master replication을 적용해봐야겠다.
mariadb를 삭제하고 다시 master-master replication을 적용하여 ansible을 돌리니, 두 서버의 DB 모두에서 replication 오류가 발생한다. reset master를 해도 해결이 되지 않는다. 양쪽 모두에서 stop slave, reset master를 하고 하나씩 start slave를 해주니 일단 wait 상태가 되긴 한다. 이렇게 해주고 나니 양쪽 모두에서 insert를 해도 상대방에 잘 반영된다.
ansible을 다시 실행해도 깨지지 않나? 다시 실행하니 깨진다. stop slave; reset master; start slave 해도 복구가 안된다. 일단 replication 구성되면 가만히 내버려 둬야 하나보다. 일단 여기까지 하고 DB를 지우자.
DB를 지운 후 ansible 수행하니 replication 오류가 발생해있다. stop slave; reset master; start slave 하니 정상 상태로 돌아온다. 상호 업데이트도 서로 잘 반영되고.
한쪽 DB를 죽이고 반대쪽에 수정이 일어난 후에 죽은 DB를 살려도 깨지지 않나? 양방향 모두? 한쪽의 mysql 서비스를 중단시키고 반대쪽에서 레코드 수정 후 mysql 다시 기동하니, 죽었던 동안 변경된 사항이 잘 반영된다. 양 방향 모두.
Online Migration
TokuDB는 online migration을 지원하는 MySQL 엔진이다. Commercial로 판매함.
Online migration tools
osc (facebook)