[DB] 글로벌 트랜잭션 아이디 기반 복제

이열음·2022년 12월 6일
0

MYSQL 5.5까지는 바이너리 로그 파일 위치 기반 복제만 가능했다. 근데 이후부터는 GTID 기반 복제도 가능해졌다.

나오게 된 배경

이벤트는 바이너리 로그 파일명과 파일 내 위치값의 조합으로 식별한다. 근데 이건 로그파일이 저장되어있는 소스서버에서만 유효하다. 따라서 레플리카 서버에서도 동일한 파일명의 동일한 위치에 저장된다는 보장이 없다.

왜냐면?

복제에 투입된 레플리카 서버들마다 동일한 이벤트에 대해 다른 식별값을 가지게 될 수 있다

  • 어떤 경우가 있을지? → 복제를 뜨는 시점이 슬레이브마다 다르면 그럴 수 있다.
    • 유저 3번까지 뜨고 1번 슬레이브 생성
    • 유저 4번 생성 = 바이너리 로그 파일명 + 파일 내 위치값(1)
    • 2번 슬레이브 덤프로 생성
    • 유저 5번 생성
      • 첫번째 덤프 : 바이너리 로그 파일명 + 파일 내 위치값(2)
      • 두번째 덤프 : 바이너리 로그 파일명 + 파일 내 위치값(1)
  • 아니 그리고 다운됐을때 복구도 어렵다.

레플리카 두개있는데 하나가 지연때문에 동기화가 안된상태에서 소스서버가 뻑나면?

동기화 되어있는애가 소스로 승격되고 동기화 안된애가 레플리카로 갈텐데 이때 동기화가 안되어있어서 select 쿼리 분산용으로 사용할 수 없다. 승격된 소스의 릴레이로그를 가져와서 쓰면 되지 않나? 싶긴한데 MYSQL 서버의 릴레이로그는 불필요하다 싶으면 지워버려가지고 남아있는 지점이 일치할거라 확신할 수 없다.

GTID란?

글로벌 트랜잭션 아이디. 데이터베이스에서 커밋되는 트랜잭션마다 고유하게 설정되는 값. 마스터 뿐 아니라 레플리카에서도 고유함. source_id:transaction_id 형태로 구성되어 있다. 이전의 바이너리 로그는 로그파일명과 파일 내의 위치로 식별하나 GTID는 위치나 이름과는 무관하게 생성되는 트랜잭션 식별자로, 모든 서버에서 고유하다.

c3bae1f6-7a74-11eb-9bd7-020017084359:24 이렇게 생겼다.

+) source_id란?

서버를 식별하는데 사용되는 값. server_uuid값이 일반적이다.

GTID 기반 복제라면?

GTID 활성화와 복제는 전혀 다른 의미라 수동으로 이거 기반으로 복제한다는 설정이 필요하다. 안하면 바이너리 로그 기반으로 복제하게 된다. 소스서버를 포함한 복제서버들 전부 gtid_mode라는 환경변수를 On으로 활성화해주면 된다.

글로벌 트랜잭션 아이디니까 어떤 릴레이로그든 같은 트랜잭션 아이디를 가지고 있다. 어떤 바이너리 로그부터 시작해야하는지도 아마 걍 트랜잭션아이디 기준으로 자기가 알아서 찾아가지고<이거 맞나?>, 바이너리 로그명이나 시작할 위치를 따로 지정해줄 필요도 없다. 그냥 레플리카가 가지고있는 파일 내에서 복제 안떴다고 표시된 그 위치부터 복구하면 된다. 모든 레플리카가 같은 트랜잭션 아이디를 공유하니까 토폴로지 변경때도 간단하게 동기화할 수 있다. 머리를 많이 안굴려도 된다는게 장점.

주의할 점

MYSQL 8.0.17 버전 이상이면 커밋과 동시에 GTID 저장하는 mysql.gtid_executed 테이블에 바로 저장된다.

근데 이전버전이면 바이너리 로그파일 로테이션되거나 MYSQL 서버 종료될때 한방에 저장된다고 한다. 이전버전을 쓴다면 gtid_executed 시스템변수로 가장 최근 실행된 트랜잭션을 따로 확인해줘야한다.

mysql.gtid_executed 테이블

이 테이블 transaction id랑 interval_start, interval_end 세 컬럼으로 이루어져있는데, 이때 interval_start, interval_end는 압축에 사용된다. 매 커밋마다 트랜잭션 아이디를 저장하는게 디스크공간 차지하는거기도 하고 크게 쓸일이 없어서 특정주기가 되면 MYSQL이 자동으로 압축을 하는데(바이너리 로그 활성상태라면!) interval_start, interval_end이 연속된 것들을 모아서 1건의 레코드로 압축한다. 만약 바이너리 로그가 활성화되어있지 않으면 thread/sql/compress_gtid_table이라는 포그라운드 스레드에 의해 압축을 한다. 이 스레드는 gtid_executed_compression_period 시스템 변수에 지정된 수까지 도달했을때 스레드에서 압축을 하고, 다음 주기가 돌아올때까지 슬립상태로 대기한다.(0이면 압축x)

0개의 댓글