Real MySQL 책에 복제(Replication)에 관한 내용을 읽고 있었던 중 이런 내용이 있었다.
마스터 서버에서 수많은 동시 사용자가 실행한 데이터 변경 쿼리 문장이 슬레이브 서버에서는 하나의 스레드로 모두 처리돼야 한다(이 부분은 지금의 구조상 피해 갈 방법이 없다).
즉, 마스터 서버에서는 바이너리 로그를 기록하는데 이때 "Binlog dump" 라는 스레드가 이 일을 전담하며 하나의 마스터 서버에 N개의 슬레이브가 연결돼 있다면 "Binlog dump" thread 가 10개가 생긴다. 그리고 슬레이브 서버에서는 relay log 가 존재하는데, 이 relay log 는 마스터의 변경내역이 기록된 로그 파일이며 슬레이브 서버의 I/O thread 가 마스터 서버에 접속해 변경 내역을 해당 파일에 기록한다. 그리고 relay log 에 기록된 내역을 sql thread 가 재실행하면서 마스터와 동일하게 유지된다.
이처럼 위에서 간단하게 마스터와 슬레이브 서버가 동일하게 데이터가 유지되는지에 대해 이야기 했다. 그렇다면 왜 single thread 로 동작을 하도록 했을까라는 생각이 들었다. 왜냐하면 매우 많은 트래픽을 감당하는 DB 일 수록 마스터 서버에서 발생하는 수많은 데이터 변경 이벤트를 슬레이브 서버에서는 하나의 sql thread 로 처리를 한다고 하면 당연히 느릴 것이라고 생각되기 때문이었다(중간 중간에 느린 쿼리도 있을 것이다). 물론 5.6 버전부터는 스키마 별로 sql thread 를 사용할 수 있는 옵션이 있긴 하다. 우선 하나의 스키마에 대해 multi thread 로 동작을 했을 때의 문제점들을 생각해보자.
- multi thread 로 동작하며 막무가내로 쿼리를 실행하면 트랜잭션 순서가 불일치 될 것 같다. 예를 들어 id 가 1~10 까지인 데이터를 넣는데 중간에 데이터가 빠진다던가 하는 그런 사이드 이펙트.
- multi thread 로 동작하게 되면서 lock 에 대한 관리
더 많은 이유가 있겠지만 우선 지금 생각나는 건 저런 부분이다. 저런 이유로 우선 single thread 로 동작을 하게 끔 하지 않을까 싶다.
그 이후 버전에서는 이러한 부분들을 개선하려고 여러 옵션들이 추가된 보인다. 우선 지금 작성 중인 버전 기준으로는 스키마 별로 relay log 를 남기게 되는데 LOGICAL_CLOCK 모드를 사용하면 마스터의 Binlog Group Commit 을 단위로 하여 동시해 처리할 수 있는지 없는지 판단해 multi thread 로 동작하게끔 한다. 그래도 검색해보니 설정했다고 확 빨라지지는 않는 것을 보며 정답은 아닌 듯하다.
MySQL 8.0 까지는 아직 찾아보지 않았다. 찾을 때마다 글을 업데이트 할 생각이다. 물론 복제 지연을 실제로 느껴보지도 않았지만 그래도 나중에 도움이 될까 싶기도 하고 누군가 나와 같은 생각을 할 수 있으니 글을 작성해본다.
참고할만한 사이트이다.
https://rastalion.me/mariadb-replication/
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=seuis398&logNo=220589886414