[Real MySQL 8.0 2] 16.3 복제 - 복제 타입
MySQL의 복제는 소스 서버의 바이너리 로그에 기록된 변경 내역(바이너리 로그 이벤트)들을 식별하는 방식에 따라 바이너리 로그 파일 위치 기반 복제(Binary Log File Position Based Replication)와 글로벌 트랜잭션 ID 기반 복제(Global Transaction Identifiers Based Replication)로 나뉘는데, 각 방식의 동작 원리와 구축 방법을 살펴보겠다.
1. 바이너리 로그 파일 위치 기반 복제
바이너리 로그 파일 위치 기반 복제는 MySQL에 복제 기능이 처음 도입됐을 때부터 제공된 방식으로, 레플리카 서버에서 소스 서버의 바이너리 로그 파일명과 파일 내에서의 위치(Offset 또는 Position)로 개별 바이너리 로그 이벤트를 식별해서 복제가 진행되는 형태를 말한다.
아래 쿼리로 현재 MySQL의 바이너리 로그 파일명(binlog.000183)과 위치(157) 등을 볼 수 있다.
1
2
3
4
5
6
SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000183 | 157 | | | |
+---------------+----------+--------------+------------------+-------------------+
아래의 쿼리로 MySQL의 바이너리 로그들도 볼 수 있다. binlog.000167은 MySQL 실습 테이블을 적재했을 때 로그, binlog.000171는 공간 검색 쿼리가 적재된 로그, binlog.000178는 타임존을 적재했을 때 로그인데 다른 로그 파일들보다 크기가 큰 것을 볼 수 있었다. 아무 쿼리가 없어도 MySQL 서버 재시작 등 여러 요인으로 별도의 로그 파일이 생성되기도 했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000152 | 201 | No |
| binlog.000153 | 201 | No |
| binlog.000154 | 201 | No |
| binlog.000155 | 201 | No |
| binlog.000156 | 201 | No |
| binlog.000157 | 201 | No |
| binlog.000158 | 201 | No |
| binlog.000159 | 201 | No |
| binlog.000160 | 201 | No |
| binlog.000161 | 201 | No |
| binlog.000162 | 201 | No |
| binlog.000163 | 201 | No |
| binlog.000164 | 201 | No |
| binlog.000165 | 201 | No |
| binlog.000166 | 201 | No |
| binlog.000167 | 89051246 | No |
| binlog.000168 | 201 | No |
| binlog.000169 | 201 | No |
| binlog.000170 | 201 | No |
| binlog.000171 | 1306 | No |
| binlog.000172 | 201 | No |
| binlog.000173 | 201 | No |
| binlog.000174 | 201 | No |
| binlog.000175 | 201 | No |
| binlog.000176 | 201 | No |
| binlog.000177 | 201 | No |
| binlog.000178 | 802351 | No |
| binlog.000179 | 201 | No |
| binlog.000180 | 201 | No |
| binlog.000181 | 201 | No |
| binlog.000182 | 201 | No |
| binlog.000183 | 157 | No |
+---------------+-----------+-----------+
2. 글로벌 트랜잭션 ID(GTID) 기반 복제
MySQL 5.5 버전 이전까지는 복제를 설정할 때 바이너리 로그 파일 위치 기반 복제 방식만 가능했다. 즉, 복제에서 각각의 이벤트들이 바이너리 로그 파일명과 파일 내 위치 값의 조합으로 식별되는 것인데, 문제는 이 같은 식별이 바이너리 로그 파일이 저장돼 있는 소스 서버에서만 유효하다는 것이다. 동일한 이벤트가 레플리카 서버에서도 동일한 파일명의 동일한 위치에 저장된다는 보장이 없다. 한마디로 복제에 투입된 서버들마다 동일한 이벤트에 대해 서로 다른 식별 값을 갖게 되는 것이다.
교재 p.446의 그림 16.3처럼 소스 서버 A와 레플리카 서버 B, C가 있는 복제 토폴로지에서 B는 동기화가 완료됐고, C는 동기화가 진행 중일 때, 소스 서버 A에 장애가 발생 시 레플리카 서버 B를 새로운 소스 서버로 승격(Promotion)하면 당장의 서버 장애에 대응할 수 있다. 하지만 바이너리 로그 파일 위치 기반 복제 상황에서 레플리카 서버 C는 더 이상 A로부터 바이너리 로그 파일 위치를 얻을 수 없고 레플리카 서버 B의 바이너리 로그 파일 위치는 소스 서버 A와는 완전히 다르기 때문에 더 이상 동기화를 하기 어렵다. 레플리카 서버 B의 릴레이 로그가 남아있으면 이를 통해 복구를 할 수도 있지만 일반적으로 릴레이 로그는 불필요한 시점에 자동으로 삭제되므로 상당히 제한적이다.
소스 서버에서 발생한 각 이벤트들이 복제에 참여한 모든 MySQL 서버들에서 동일한 고유 식별값을 가진다면 복제 토폴로지의 변경이나 장애 복구 소요 시간을 줄일 수 있는데, 이처럼 소스 서버에서만 유효한 고유 식별 값이 아닌 복제에 참여한 전체 MySQL 서버들에게 고유하도록 각 이벤트에 부여된 식별 값을 글로벌 트랜잭션 아이디(GTID, Global Transaction Identifiers)라 하며 이를 기반으로 복제가 진행되는 형태를 GTID 기반 복제라 한다.
3. 글로벌 트랜잭션 아이디
글로벌 트랜잭션 아이디(GTID)는 소스 아이디와 트랜잭션 아이디 값의 조합으로 생성되며, 두 값은 콜론(:)으로 구분되어 표시된다. MySQL의 GTID는 서버에서 커밋된 각 트랜잭션과 연결된 고유 식별자로, 해당 트랜잭션이 발생한 서버뿐만 아니라 그 서버가 속한 복제 토폴로지 내 모든 서버에서 고유하다. GTID는 커밋되어 바이너리 로그에 기록된 트랜잭션에 한해서만 할당되며, 데이터 읽기만 수행하는 SELECT 쿼리나 혹은 sql_log_bin 설정이 비활성화돼 있는 상태에서 발생한 트랜잭션은 바이너리에 기록되지 않으므로 GTID가 할당되지 않는다.
Ref
- Real MySQL 8.0 2 - p.434 ~ p.468