MySQL Replication에 대하여

허준현·2023년 6월 11일
0

MySQL

목록 보기
2/3
post-thumbnail

MySQL에서 복제가 어떤 형식으로 이루어지는 지 알아보고 복제 시에 어떤 락이 걸리는지 알아보고 복제시에 8.0버전에서 어떤 트랜잭션을 제공하는지 알아보자.

binlog 종류

Binary log 는 DDL 과 DML 같이 MySQL 데이터베이스 내에서 발생하는 변경 내역이 저장되는 로그 파일이다. 이런 binlog 파일에 대해서 format은 총 3가지로 나눌 수 있다.

row

row : 생성/변경된 데이터의 Before/After row image가 binlog에 저장하여, 사이즈가 statement보다 크게 생성된다.

MYSQL에서 기본적으로 reapeatable read 를 사용하면 다른 방식 format을 사용해도 되지만 committed read를 하는 경우에는 일관성을 위해 row format을 사용해야 한다.

해당 image저장되는 방식에는 3가지가 있으며 Full 방식을 주로 사용한다.

FULL :변경 전/후 이미지 전체를 binlog에 기록 (Default)
MINIMAL : 최소한의 값만 로깅,변경된 행을 식별하는 데 필요한 이전 이미지의 열만 기록
NOBLOB : Blob,text와 같이 사이즈가 큰 값을 제외하고 기록

mixed

mixed : row와 statement 중간 형태로 날짜와 같이 determine이 필요한 경우 row형태로 저장되는 형식이다.

statement

statement : 전통적으로 사용하던 방식으로 실행된 쿼리 구문 그대로 Binlog에 남겨지는 방식이다.

앞에서 언급한 것처럼 deterministic 쿼리문에만 해당이 된다. 매 쿼리마다 같은 결과를 반환하는 쿼리는 statement로 slave로 전달하게 되면 동일하게 같은 결과가 나오지만 now() 혹은 uuid()처럼 실행할때마다 다른 값을 반환하는 쿼리는 statement 로 처리하기 힘들다.

AWS의 Aurora MySQL Cluster는 일반적인 binlog 방식이 아닌 자체 구현한 방식을 통해 수행되며, 이 방식을 사용하면 빠르게 적용 및 복제 지연이 매우 감소하지만 slave 노드 추가로 생성시에 warm up과정에서 기존에 사용하던 binlog방식이 아니기 때문에 별도의 사용자 설정이 필요하다.

binlog 가 아닌 GTID

GTID(글로벌 트랜잭션 아이디 기반 복제) 는 Global Transaction IDentifier 약자로 MySQL 데이터베이스에서 커밋되는 각 트랜잭션과 함께 생성되고 트랜잭션에 연결되는 고유한 식별자이다.
복제의 Master 서버 뿐만 아니라 복제 대상에 속한 Replica(slave) 서버에서 고유한 식별자로 작용하여 기존의 binlog에서 읽은 시점을 가져오는 부분을 개선하였다.

GTID 는 아래와 같이 구성되어 있다.
c3bae1f6-7a74-11eb-9bd7-020017084359:24

아직 failover상황에서 복구하는 운영을 해보지 않아서 gtid가 가져다 주는 이점이 와닿지는 않는다. binlog에서 어디까지 읽었는지에 대해서 맞추기가 gtid 방식보다 어렵다는 것은 확실하다. 하지만 gtid를 사용함으로서 gtid_executed 테이블이 압축을 하더라도 점점 비대해지는 것 또한 단점인 것 같다.

참고

gtid 사용하면 이점
why use gtid in mysql

slave 에서 복제 요청 시기

  1. 슬레이브 서버가 처음으로 설정되거나 재시작 할 때 마스터 서버로부터 초기 데이터 복제를 요청하게 된다.

  2. 마스터 서버에서 변경된 데이터를 바이너리 로그로 기록하고 슬레이브 서버는
    IO Thread가 로그를 수신하여 변경하게 되며 사용자가 지정한 일정한 간격으로 마스터에게 변경 로그를 요청하게 된다.

  3. 일정 수준의 바이너리 로그가 Relay log에 쌓이게 되면 SQL Thread 를 통해서 데이터를 복제하게 된다.

  4. 슬레이브가 장애로 인해 중단되었을때 슬레이브는 중단되었던 시점을 알기 때문에 마스터에게 그 이후의 변경 사항에 대해서 데이터를 받아와 복구하게 된다.

복제 방식 두가지: async , semi-async

Async Replication

MySQL 은 기본적으로 Async Replication 을 사용한다.
Binary Log에는 MySQL의 모든 변경 사항이 기록이 되고 Slave DB에서는 binlog 를 이용 하여 복제가 수행 된다.

기존 오라클에서 RedoLog에 변경 사항을 쌓아두고 일정 수준이 되면 아카이브 파일에 옮겨가는 작업이랑 유사하며
해당 RedoLog에 쌓인 변경 사항이 disk에 쓰기 전에 인스턴스가 종료된 경우 해당 Redo, Undo 로그를 통해서 변경사항을 불러오게 된다.

앞에서 알아본 복제되는 과정을 거치고 나서 Async 방식으로 동작하기 때문에 Master 에서는 Slave의 복제 완료(성공) 여부 등을 확인 하지 않고 Master 서버 중인 트랜잭션을 종료 및 결과 반환 하게 된다. 여기서 말하는 트랜잭션은 앞에서 알아본 백업 트랜잭션을 의미한다.

단점으로는 slave 사용량, CPU 사용률 , 네트워크 속도 등 여러가지 이유로 Slave에 Replication 이 늦어질수도 있고 그에 따라 조회시점에 데이터가 차이가 발생한다.

Semi-sync Replication

Semi-sync Replication 방식은 Master DB에서 Slave 로 전달된 Relay log의 기록이 완료 되었다는 메세지(신호)를 받고나서 처리중인 transaction의 결과를 요청한 application(client)에 결과를 반환해주는 방식이다.

우리가 익히 알고 2PC에서 각 db에서 ASK를 받고 난 이후에 커밋을 하는 것처럼 동기화해준 다고 생각하였다.

Async 방식에 비하면 성능이 저하 되긴 하지만 Master 와 Slave 사이의 데이터에 대한 동기화 나 안전성 측면에서 Async 방식에 비해 더욱 보장 해줄 수 있게 된다.

Semi-sync Replication 은 전달 시기(방법)에 따라서 after_commit 과 after_sync방식으로 나뉘게 되며 이는 별도의 플로그인 설치 후 이용이 가능하다.

복제를 통해서 얻을 수 있는 이점

1. scale out

성능을 향상시키기 위해 여러 개의 복제본에 분산을 부하할 수 있다.

2. 분석

원본 데이터에서는 실시간으로 데이터가 생성되면 성능 이슈없이 slave에서 분석 할 수 있다.

replication lock이 slave에 걸리는가

당연할 수 있지만 해당 건은 마스터 서버에만 적용이 된다.
마스터 서버에서 DDL이나 일부 DML 문장에 락을 걸어 다른 스레드나 클라이언트가 해당 문장을 실행하지 못하게 하기 위함이다.
따라서 슬레이브는 별도의 lock이 적용되지 않는다.
이를 통해 복제 지연을 최소화 하고 일관된 데이터를 유지 할 수 있다.

mysql 8.0 이상에서 sql 덤프 과정

  1. mysqldump -u <사용자명> -p <데이터베이스명> <덤프파일명.sql>
  2. mysqldump 를 하기 위해 연결 및 인증을 하며 sql 덤프를 생성하게 된다.
  3. 트랜잭션 일관성을 제공하기 위해 8.0 이상부터는 --single-transaction 옵션이 적용되어 트랜잭션 일관성이 제공된다.
  4. 사용자가 입력한 데이터베이스의 스키마와 데이터가 포함된 sql 파일이 생성된다.

    innodb를 기본적으로 사용하고 있어 좀 더 향상된 backup 트랜잭션을 제공하여 write에 대해서 lock을 걸지 않으며 잠시동안만 테이블에 대한 읽기락을 건다.

profile
best of best

0개의 댓글