MySQL Replication

전영호·2024년 3월 13일

데이터베이스

목록 보기
1/2

데이터베이스 다중화

일반적으로 위와 같은 다중화 방식인 Master - Slave 방식을 많이 사용한다.
그러면 MySQL 에서는 어떻게 Replication 을 구현했는지 확인해보자.

Replication

해당 글은 MySQL 8.3 버전 기준입니다.

MySQL 의 Replication 은 Master 에서 데이터 쓰기연산이 일어날 경우, Binary Log 를 작성합니다. 그리고 Slave DB 에서 해당 Log 를 읽어서 적용하는 방식을 사용하고 있습니다.

GTID

1. 바이너리 로그 파일 위치 기반

예전 MySQL 버전에서는 로그파일 offset 기반으로 Slave 서버들이 읽고 자신의 서버에 반영하는 형식이었습니다.

위의 예시의 경우 Binary-log.00005 파일의 3번째 라인을 복제하라는 뜻이겠죠.

2. GTID 기반

지금은 GTID 라는 global transaction identifiers 를 사용하는 Transaction 기반의 형식입니다.

GTID = source_id:transaction_id
일반적으로 위와 같은 형식을 띄는데, 해당 전체 시스템에서 unique 한 값입니다.
source_id 는 마스터 DB의 uuid
transaction_id 는 트랜잭션 횟수에 따라 증가하는 정수 값입니다. 이 값은 도중에 건너뛰지 않고 일정하게 증가합니다.

auto-skip function 을 통해 하나의 GTID 를 가진 트랜잭션은 한번만 실행되는걸 보장합니다.
하나의 GTID를 가진 트랜잭션에 대한 여러 요청이 동시에 들어오면, 하나의 요청만 실행되고 나머지는 block 됩니다.

GTID 라이프 사이클
1.

  • Client 에서 트랜잭션 실행시, 서버의 UUID와 아직 사용되지 않은 가장 작은 트랜잭션 순서 번호로 구성된 GTID가 할당됩니다.
  • GTID는 트랜잭션 자체가 로그에 기록되기 바로 앞서 이진 로그(binary log)에 기록됩니다.
  • 로그에 기록되지 않는 트랜잭션은 GTID를 할당받지 않습니다.
  • 트랜잭션이 커밋될 때, GTID는 Binary Log에 원자적으로 기록됩니다.
  • 서버가 종료될 때, 이전 이진 로그 파일에 기록된 모든 트랜잭션의 GTID가mysql.gtid_executed 테이블에 기록됩니다.
  • 트랜잭션이 커밋된 직후, GTID는 gtid_executed 시스템 변수에 비원자적으로 추가됩니다.
  • gtid_executed 에 들어있는 GTID set은, 이때까지 커밋된 모든 트랜잭션의 모음입니다.
  • gtid_executed 에 들어있는 GTID set은 replication 을 진행할때, slave 서버에서 참조할 token 으로서 사용됩니다.
  • slave 서버는 binary log를 받아 relay log에 저장합니다.
  • 다음 트랜잭션을 이 GTID로 진행해야 함을 나타내기 위해 gtid_next 변수 값을 해당 GTID로 설정합니다.
    복제본은 gtid_next에 할당된 GTID가 아직 처리되지 않았는지 확인합니다.
  • slave 서버의 쓰레드는 해당 GTID 트랜잭션을 실행 하기전에 먼저 이전에 해당 GTID 트랜잭션이 실행된적이 없는지 확인합니다.
  • 또한, 동시에 다른 쓰레드에서 해당 트랜잭션이 진행되는지 확인 합니다.
  • 이를 통해, 하나의 GTID 트랜잭션은 단 한번만 실행되도록 보장합니다.
  • 해당 GTID 트랜잭션을 실행합니다.

Semisynchronous Replication

완전 비동기 방식은 slave 서버들이 언제 master에 적용된 트랜잭션을 반영하는지 알 수 없습니다.

반동기 방식의 경우, 최소한 하나의 slave 서버가 transaction 정보를 전달 받았다는 ack 메세지를 받은후에 master 서버에서 커밋을 진행합니다. (몇개의 서버가 전달 받고 master 서버가 커밋을 진행할지는 설정할 수 있습니다.)

이 때, slave 서버에서 ack 를 보내는 시점은 transaction 이 만료되었을 때가 아닙니다.
Relay Log 에 저장된 직후에 ack 를 보냅니다.

Replication Format

1. Statement-based binary logging

SQL 문을 바이너리 로그에 작성한다.

장점

  • 오랫동안 사용된 기술
  • 훨씬 더 적은 데이터가 log file에 작성된다
  • db의 어떤 변화라도 기록할 수 있다.

단점

  • nondeterministic 한 행동을 할 경우, unsafe 할 위험이 존재한다.
  • insert ... select 문의 경우 훨씬 더 많은 row-level lock 이 사용된다

2. row-based logging

각각의 Row 들이 어떻게 바뀌었는지 저장해 둔다.

장점

  • 훨씬 더 safe 하게 replicate 가능하다
  • 몇몇의 경우 훨씬 더 적은 row-lock 이 필요하다

단점

  • 훨씬 더많은 데이터가 log file 에 작성된다.
  • BLOB 데이터를 작성하는 경우 더 많은 시간이 걸립니다.
  • slave에서는 master에서 받은 statement를 직접 확인할 수 없습니다. 단, mysqlbinlog 유틸리티를 사용하면 변경된 데이터를 확인할 수 있습니다.

Reference

https://www.youtube.com/watch?v=NPVJQz_YF2A
https://dev.mysql.com/doc/refman/8.3/en/replication.html

0개의 댓글