GTID 개념

- GTID(Global Transaction Identifiler)는 원본 서버(Source)에서 Commit된 각각의 트랜잭션들이 가지게되는 고유한 전역 식별자로 원본 서버에만 고유한것이 아니라 복제 설정의 모든 서버에서 고유한 값을 가진다. 

- 모든 트랜잭션과 모든 GITD 사이에는 일대일 매핑이 있다. 

 

GITD 부여 방식 

- auto.cnf 파일에 설정된 server-uuid:transaction_id 로 표시 되며 transaction_id는 트랜잭션이 Commit된 순서에 의해 결정된다. (server-uuid 로 원본서버를 식별한다.)

 

GTID 확인 

- Binary Log, SHOW SLAVE STATUS 문에서 확인 가능

- mysqlbinlog --base64-output=DECODE-ROWS 문으로 log file에서 확인하거나 SHOW BINLOG EVENTS의 결과에서도 확인 가능

- SHOW MASTER STATUS, SHOW SLAVE STATUS 문의 결과와 같이 동일한 서버에서 생성된 GTID의 순서는 아래와 같이 단문으로 축소되어 보여진다. 

  3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5

- MySQL 5.6.6 이상부터 START SLAVE 문에 SQL_BEFORE_GITDS, SQL_AFTER_GTIDS 옵션을 제공한다. 

 

GTID 세트 

- GTID 세트는 다음과 같이 표시되는 글로벌 트랜잭션 식별자 세트 

gtid_set:
    uuid_set [, uuid_set] ...
    | ''

uuid_set:
    uuid:interval[:interval]...

uuid:
    hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh

h:
    [0-9|A-F]

interval:
    n[-n]

    (n >= 1)

- GTID 세트는 MySQL 서버에서 여러가지 방식으로 사용된다. 

  - EX) gtid_executed, gtid_purged 시스템 변수로 저장된 값은 GTID 세트로 표시된다.

         GTID_SUBSET(), GTID_SUBTRACT() 함수는 GTID 세트 입력값이 필요하다.

- GTID 는 항상 원본(소스)와 복제본간에 유지된다. 

   바이너리 로그를 검사하여 복제본에 적용된 모든 트랜잭션의 원본(소스)를 항상 확인할 수 있다. 

- 주어진 GTID를 가진 트랜잭션이 주어진 서버에서 Commit 되면 동일한 GTID를 가진 모든 후속 트랜잭션이 해당 서버에서 무시된다. 원본(소스)에서 커밋 된 트랜잭션은 복제본에 한번만 적용될 수 있으므로 일관성이 보장된다. 

- GTID를 사용할때 복제본에는 소스의 파일 이름 및 해당 파일 내의 위치와 같은 비 로컬 데이터가 필요하지 않다. 

- 소스와 동기화하는데 필요한 모든 정보는 복제 데이터 스트림에서 직접 가져온다. 

- 원본, 복제본 간의 데이터 흐름의 시작, 중지 또는 재게하는 시점을 결정하는데 필요했던 file-offset pairs를 대체한다. 

- 복제를 위해서 GTID를 사용할때 CHNAGE MASTER TO 구문에서 MASTER_LOG_FILE, MASTER_LOG_POS 옵션을 사용할 필요가 없다. 대신 MASTER_AUTO_POSITION 옵션을 사용한다. 

 

GTID의 생성 및 수명주기는 다음 단계로 구성된다. 

1. 트랜잭션이 원본(소스)에서 실행되고 Commit

   이 트랜잭션에는 원본(소스)의 UUID와 서버에서 사용되지 않은 가장 작은 트랜잭션 시퀀스 번호(0보다 큰)를 사용하여 GTID가 할당된다. GTID는 원본(소스)의 바이너리 로그에 기록된다. 

2. 바이너리 로그 데이터가 복제본으로 전송되고 복제본의 릴레이 로그에 저장되면 복제본은 GTID를 읽어서 gtid_next 시스템 변수값으로 설정한다. 

3. 복제본은 이 GTID가 잔체 바이너리 로그에 트랜잭션을 기록하는데 아직 사용되지 않았는지 확인한다. 

   이 GTID가 사용되지 않은 경우에만 복제본은 GTID를 사용하여 트랜잭션을 적용한다. (그리고 트랜잭션을 바이너리 로그에 기록한다.) 

   트랜잭션을 실행하기 전에 트랜잭션의 GTID를 먼저 읽고 확인하는것은, 아직 Commit되거나 적용되지 않은 트랜잭션에 대해 복제본은 이 GTID가 있는 이전 트랜잭션이 복제본에 적용되지 않았을뿐만 아니라 다른 세션이 GTID를 읽지 않았음을 보장한다. 

4. gtid_next 값이 비어있지 않기 때문에 복제본은 이 트랜잭션에 대한 GTID를 생성하려고 시도하지 않고 이 변수에 저장된 GTID(원본에서 얻은 GTID)의 트랜잭션(바이너리 로그에 저정된)을 실행한다. 

 

mysql.gtid_executed 테이블 (5.7 에서 추가됨)

- 현재 활성화된 바이너리 로그 파일에 저장된 트랜잭션을 제외하고 MySQL 서버에 적용된 모든 트랜잭션에 할당된 GTID를 저장하는데 사용되는 테이블 

- 이 테이블의 행에는 각 GTID 또는 GTID 집합에 대해 원본 서버의 UUID와 집합의 시작 및 종료, 트랜잭션 ID가 포함된다. 단일 GTID만 참조하는 행의 경우 마지막 두 값은 동일하다. 

- 이 테이블은 복제본에서 바이너리 로깅이 비활성화 된 경우 복제본이 GTID를 사용할 수 있드록 하고 바이너리 로그가 손실된 경우 GTID를 유지할 수 있게 해준다. 

- RESET MASTER 문을 실행할 경우 mysql.gtid_executed 테이블은 초기화된다.

- gtid_mode 가 ON 또는 ON_PERMISSIVE 모드일 때만 GTID가 mysql.gtid_executed 테이블에 저장된다. 

 

 

GTID 의 Life Cycle

1. 트랜잭션이 커밋되면 GTID를 할당 받고 원본의 바이너리 로그에 기록된다. 

2. 할당된 GTID는 gtid_executed 시스템 변수(@@GLOBAL.gtid_executed)와 mysql.gtid_executed 테이블에 저장된다. 

3. 원본의 바이너리 로그 데이터가 복제본의 릴레이 로그에 저장되면 복제본은 GTID를 읽고 gtid_next 시스템 변수를 설정한다. 

4. 복제본에서 gtid_next 에 설정된 GTID의 트랜잭션이 반영되지 않았을 경우 반영한다. 

5. 복제본에 바이너리 로그가 활성화된 경우 커밋후 GTID를 바이너리 로그에 기록하고 복제본의 gtid_executed 시스템 변수(@@GLOBAL.gtid_executed)와 mysql.gtid_executed 테이블에 저장된다.  바이너리 로그가 비활성화된 경우 바이너로 로그에 기록하는 부분을 제외하고는 동일하게 처리된다. 

 

GTID Auto-Positioning

- 복제구성시 GTID를 사용할 경우 복제본이 원본과 동기화하는데 필요한 모든 정보를 복제 데이터 스트림에서 직접 가져온다. 

- 복제 구성시 MySQL 8.0.23 버전부터는 CHANGE REPLICATION SOURCE TO  문을 사용한다. 이전 버전의 경우 CHANGE MASTER TO 문을 사용한다. GTID 사용시  SOURCE_AUTO_POSITION  또는 MASTER_AUTO_POSITION 옵션을 사용한다.  SOURCE_LOG_FILE, MASTER_LOG_FILE, SOURCE_LOG_POS, MASTER_LOG_POS 등의 옵션을 사용하지 않는다. 

- 복제본에 GTID가 활성화 (GTID_MODE=ON, ON_PERMISSIVE,또는 OFF_PERMISSIVE) 되고 MASTER_AUTO_POSITION 옵션이 활성화되면 원본에 연결하기 위한 바이너리 파일의 위치를 찾는다. 

- 복제본은 원본에 수신, 커밋 또는 둘다 수행한 트랜잭션이 포함된 GTID 세트를 보내고 원본 서버는 이 GTID 세트에 포함되지 않은 바이너리 로그의 모든 트랜잭션을 전송한다. 이때 원본에서 전송해야되는 트랜잭션이 바이너리 로그에서 제거되었거나 다른 방법으로 gtid_purged 시스템 변수에 GTID가 추가된 경우 복제본에 ER_MASTER_HAS_PURGED_REQUIRED_GTIDS 오류를 전송하고 복제는 시작되지 않는다. 

- 누락된 트랜잭션의 GTID는 원본서버의 에러로그에 warning message ER_FOUND_MISSING_GTIDS 에 기록된다.

- 이 상황에서 MASTER_AUTO_POSITION 옵션을 사용하여 복제를 구성하기 위해 복제본을 복구하려면 다른 원본에서 ER_FOUND_MISSING_GTIDS에 기록된 GTID의 트랜잭션을 복제하거나 원본서버를 백업받아 복제본을 새로 구성해야 한다. ( binlog_expire_logs_seconds 가 발생하지 않도록 바이너리 로그 보관기간을 조정한다.)

 

 

참고

https://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html

https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-concepts.html

https://dev.mysql.com/doc/refman/8.0/en/replication-gtids-concepts.html

https://dev.mysql.com/doc/refman/8.0/en/replication-gtids-lifecycle.html

https://dev.mysql.com/doc/refman/8.0/en/replication-gtids-auto-positioning.html

 

 

 

 

'MySQL' 카테고리의 다른 글

GTID 사용시 복제본 복구  (0) 2021.06.10
GTID를 사용한 복제구성  (0) 2021.06.09
MySQL InnoDB Row 형식  (0) 2021.06.04
online ddl 알고리즘  (0) 2021.05.27
binlog format  (0) 2021.05.15

+ Recent posts