MySQL GTID 를 사용한 Replication(복제) 설정

Share

Last Updated on 6월 26, 2023 by Jade(정현호)

GTID

GTID 는 Global Transaction IDentifier 약자로 MySQL 데이터베이스에서 커밋되는 각 트랜잭션과 함께 생성되고 트랜잭션에 연결되는 고유한 식별자 입니다 

이 식별자는 복제의 Master 서버 뿐만 아니라 복제 대상에 속한 Replica(slave) 서버에서 고유한 식별자 입니다 

GTID 는 아래와 같이 구성되어 있습니다.
GTID = source_id:transaction_id

source_id 는 originating 서버를 식별 하는데 사용되며 일반적으로 server_uuid가 이 용도로 사용 됩니다.

server_uuid 는 아래와 같이 확인 할 수 있습니다.

mysql> select @@server_uuid;
+--------------------------------------+
| @@server_uuid                        |
+--------------------------------------+
| c3bae1f6-7a74-11eb-9bd7-020017084359 |
+--------------------------------------+


c3bae1f6-7a74-11eb-9bd7-020017084359:24
-> 24번째 트랜잭션을 의미


master 와 slave 간 복제 시작, 중지의 기준이 되었던 binlog 파일명과 pos 정보 대신 GTID 를 사용할 수 있으며 다음과 같은 특징을 가지게 됩니다.

 - CHANGE MASTER TO 의 MASTER_LOG_FILE, MASTER_LOG_POS 의 사용하지 않아도 됨
 - GTID 정보만으로 master - slave 간의 일관성 확인이 쉽게 수행됨
 - slave에 반영된 gtid 트랜잭션이 mysql.gtid_executed 로 관리되기 때문에 중복 수행 안됨

mysql> select @@global.gtid_executed;
+-------------------------------------------+
| @@global.gtid_executed                    |
+-------------------------------------------+
| c3bae1f6-7a74-11eb-9bd7-020017084359:24   |
+-------------------------------------------+


mysql> select * from mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid                          | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| c3bae1f6-7a74-11eb-9bd7-020017084359 |              1 |           24 |
+--------------------------------------+----------------+--------------+

트랜잭션이 커밋되면 GTID를 할당 받고 binlog 에 기록이 되게 됩니다. 할당된 GTID 는 gtid_executed system variable 과 mysql.gtid_executed 에 저장되게 됩니다
           

파라미터 설정

gtid 를 사용하여 복제하기 위해서 gtid 관련된 파라미터를 사전에 설정 후 MySQL 서버의 재시작을 해야 합니다.

포스팅에서는 아래와 같이 설정 하였으며 gtid 설정 관련하여 필요한 파라미터는 아래 2개 입니다.
(Master/Slave 모두 설정)

gtid-mode=ON
enforce-gtid-consistency=ON
log_slave_updates=ON
log-bin=binlog (파일명은 예시임)

[root]# vi /etc/my.cnf

# master
[mysqld]
server-id=1
log-bin=binlog
gtid-mode=ON
enforce-gtid-consistency=ON
log_slave_updates=ON


# slave 
[mysqld]
server-id=2
log-bin=binlog
gtid-mode=ON
enforce-gtid-consistency=ON
log_slave_updates=ON


# 설정 후 재시작 
[root]# systemctl restart mysqld



# 재시작 후 조회
mysql> show variables like '%gtid_mode%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| gtid_mode     | ON    |
+---------------+-------+


gtid_mode 에는 설정할 수 있는 값은 4개가 있으며 각각의 내용은 다음과 같습니다.

   Master 입장에서의 동작

 Slave 입장에서의 동작

 OFF

 트랜잭션에 Global Trx ID 값을 부여하지 않음

 복제된 트랜잭션에 Global Trx ID가 부여되어 있으면 처리불가

 OFF_PERMISSIVE

 복제된 트랜잭션이 어떤 방식이든지 처리 가능

 (Anonymous / GTID 둘다 처리 가능)

 ON_PERMISSIVE

  트랜잭션에 Global Trx ID 값을 부여

 ON

 복제된 트랜잭션에 반드시 Global Trx ID가 부여되어 있어야 처리 가능


MSR(Multi Source Replication) 을 사용하는 환경에서 복제가 되는 Slave 인스턴스에 MSR 채널별 다른 복제 방법을 사용하면 아래와 같이 에러 발생 됩니다.

Last_IO_Error: The replication receiver thread cannot start because the master has GTID_MODE = OFF and this server has GTID_MODE = ON.


이럴 경우 gtid_mode=off_permissive 으로 설정하면 Binlog Position 방식과 GTID 방식의 마스터 Source 를 같이 혼용(Mixed) 하여 설정 할 수 있습니다.

5.7.6 버전 부터 DB를 내리지 않고 GTID 모드를 변경 할 수 있습니다.



[참고] 포스팅에서는 gtid 관련된 내용과 편의성을 위해서 기본 async 으로 진행 하였습니다
gtid 방식이 아닌 바이너리 로그 파일 위치 기반의 복제 방식에 대해서는 아래 포스팅을 참조하시면 됩니다.

 



[참고] SSL 기반의 MySQL 복제 구성(Replication) 관련해서는 아래 포스팅을 참조하시면 됩니다.

         

유저 생성 및 mysqldump 수행

파라미터 설정이 완료 되었다면 복제 전용 유저 생성mysqldump 를 수행 하도록 하겠습니다.
       

Replication 전용 유저 생성

먼저 복제 전용 유저를 생성을 하도록 하겠습니다.

mysql> create user 'repl_user'@'%' IDENTIFIED WITH mysql_native_password BY 'Repl_user1234!@#$';
mysql> grant replication slave,replication client on *.* to 'repl_user'@'%';
mysql> flush privileges;

*  유저명 과 패스워드는 예시 입니다.
        

mysqldump 수행

초기 데이터 적재를 위해 mysqldump 를 수행하도록 하겠습니다.

mysql> mysqldump -u아이디 -p패스워드 -v --databases testdb \
 --quick --single-transaction --routines --set-gtid-purged=ON \
 --triggers --extended-insert --master-data=2 \
 | gzip > /root/db_backup/testdb.sql.gz

or 

## login-path 이용시
mysql> mysqldump --login-path=dba -v --databases testdb \
 --quick --single-transaction --routines --set-gtid-purged=ON \
 --triggers --extended-insert --master-data=2 \
 | gzip > /root/db_backup/testdb.sql.gz


* 포스팅에서는 1개의 데이터베이스만을 dump/load 하였습니다. 

[참조] --login-path 에 관해서는 아래 포스팅을 참조하시면 됩니다.

            

다른 서버로 전송 및 DataLoad

파일 전송 및 압축을 해제, 그리고 압축 해제된 SQL 파일을 통해 데이터를 Load 합니다.

# Master 서버 : 파일 전송
[root]# rsync -avzr --progress testdb.sql.gz root@다른서버:~/


# Slave 서버 : 압축 해제 및 데이터 Load
[root]#  gunzip testdb.sql.gz

mysql> source testdb.sql

                 

Replication 설정

slave 서버에서 아래와 같이 change master 를 수행하여 복제를 설정 합니다.

# 복제 설정
mysql> CHANGE MASTER TO MASTER_HOST="wmp1",
MASTER_USER='repl_user',MASTER_PASSWORD='Repl_user1234!@#$',
MASTER_AUTO_POSITION=1;

# 복제 시작 및 확인
mysql> start slave;
mysql> show slave status\G

 

Note

8.0.23 부터 명령어가 일부 변경 되었습니다.

CHANGE MASTER TO 에서 CHANGE REPLICATION SOURCE TO 로 변경 되었으며 MASTER_AUTO_POSITION 에서 SOURCE_AUTO_POSITION 로 변경 되었습니다.



• 복제 수행 여부 간단 확인

# Master Server 
mysql> use testdb;
Database changed

mysql> create table test_1 (
    no int(10) auto_increment , 
    col1 varchar(10), 
    primary key(no));
Query OK, 0 rows affected (0.01 sec)

mysql> insert into test_1 values(1,'a');
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test_1;
+----+------+
| no | col1 |
+----+------+
|  1 | a    |
+----+------+
1 row in set (0.00 sec)



# Slave Server
mysql> use testdb;
Database changed

select * from test_1;
+----+------+
| no | col1 |
+----+------+
|  1 | a    |
+----+------+
1 row in set (0.00 sec)

                 

conclusion

GTID 를 사용한 Replication 에는 몇가지 제약 사항이 있습니다 자세한 사항은 아래 도큐먼트를 확인 해보시면 되며 대표적으로 미지원 되는 기능이 CTAS 입니다.

5.7 버전 doc/replication-gtids-restrictions
8.0 버전 doc/replication-gtids-restrictions

mysql> create table tb_test_ctas as select * from tb_test;
ERROR 1786 (HY000): Statement violates GTID consistency: CREATE TABLE ... SELECT.


GTID 환경에서의 제약사항은 아래와 같이 like 로 생성 후 insert select 는 가능 합니다.

mysql> create table tb_test_like like tb_test;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into tb_test_like 
    -> select * from tb_test;
Query OK, 8130 rows affected (0.32 sec)
Records: 8130  Duplicates: 0  Warnings: 0


제약 사항은 버전의 변경에 따라 변경이 되며, MySQL 8.0.21 에서 부터는 CTAS 사용 가능 하도록 개선 되었습니다.

This restriction is lifted in MySQL 8.0.21 on storage engines that support atomic DDL. In this case, CREATE TABLE ... SELECT is recorded in the binary log as one transaction


GTID 의 사용이 확대되는 추세이며, Cloud의 완전관리형 Database(PaaS) 인 RDS 나 MDS 와 같은 서비스에도 GTID 를 통해서 IDC 나 다른 클라우드내 MySQL 간의 Outbound Replication 을 구성할 수 있기도 합니다.

8.0.21 에서 부터는 CTAS 에 대한 제약도 개선 되었기 때문에 사용을 고민해보는 것도 좋을 것 같습니다.

[참고] GTID 사용 환경에서 Replica(Slave)에서 에러가 발생되어 Skip 이 필요한 경우 조치는 아래 포스팅을 참조하시면 됩니다.

           

Reference

Reference link
 • dev.mysql.com/replication-gtids-lifecycle
 • dev.mysql.com/replication-msr
 • 5.7 dev.mysql.com/replication-gtids-restrictions
 • 8.0 dev.mysql.com/replication-gtids-restrictions
 • blog.naver.com/seuis398


관련 된 다른 글

 

 

 

 

 

 

 

 

4
0
글에 대한 당신의 생각을 기다립니다. 댓글 의견 주세요!x