MySQL Multi Source Replication - Replicate_Rewrite - MSR Rewrite

Share

Last Updated on 1월 20, 2024 by Jade(정현호)

안녕하세요 
이번 포스팅은 MySQL 의 Multi Source Replication(MSR) 환경에서 Source 의 DB(스키마명)명이 같을 경우 DB 명을 변경하여 사용하는 REPLICATE_REWRITE_DB 에 대해서 확인해보려고 합니다. 

테스트 MySQL 버전: 8.0.27 

해당 포스팅은 아래 포스팅과 연관된(이어지는) 포스팅입니다 

REPLICATE-REWRITE-DB

Rewrite 설정은 my.cnf 에 설정하거나 CHANGE REPLCATION FILTER 를 통해서 할 수 있습니다.

my.cnf 에 설정하는 형태에 대해서 확인해 보도록 하겠습니다.
잠시) REPLICATE-REWRITE 기능은 MSR 이 아닌 1:N 구조의 Replication 에서도 목적에 따라서 사용할 수 있습니다

MySQL 의 MSR 구성 시 Slave(Replica) 에서는 connection metadata repository 와 applier metadata repository 에 대한 정보가 TABLE 에 저장이 되어야 합니다. 그래서 master_info_repository 와 relay_log_info_repository 파라미터를 TABLE 로 설정 해야 합니다

master_info_repository 과 relay_log_info_repository 의 기본값은 기존까지는 FILE 이었고, MySQL 8.0.23 버전 부터 Deprecated 가 되었으며, 이 시스템 변수에 대한 값은 MySQL 8.0.23 버전 부터는 TABLE 이 기본값으로 사용됩니다.


포스팅에서의 환경에서 복제 구성 내역(시나리오) 아래와 같습니다.
 - Source DB 1 복제하려는 DB 명 : tdb
 - Source DB 2 복제하려는 DB 명 :tdb 

3번째 서버인 MSR 복제 대상 서버에서 설정
 - Source DB 1의 tdb 는 re_db1 로 rewrite 로 설정
 - Source DB 2의 tdb 는 re_db2 로 rewrite 로 설정

이미지로 표현하면 아래와 처럼 복제 Rewrite 가 적용된 MSR을 구성을 하려고 합니다.


위의 복제 구성 내용에 대해서 my.cnf 에 아래와 같이 MSR 과 Rewrite 에 관한 내용을 추가로 설정을 진행하도록 하겠습니다.

[mysqld]
master_info_repository = 'TABLE'
relay_log_info_repository = 'TABLE'

replicate-do-db = ch_master1:re_db1
replicate-do-db = ch_master2:re_db2

replicate-rewrite-db=ch_master1:tdb->re_db1
replicate-rewrite-db=ch_master2:tdb->re_db2

replicate-rewrite-db 만 설정을 해도 각 Source(Master) 의 tdb 라는 데이터베이스에서 발생된 변경사항(테이블 생성, 데이터 변경 등등) 은 tdb->re_db1 또는 re_db2 로 설정된 내역대로 Rewrite 되어 복제가 되긴 합니다.

다만 설정된 Source(Master) 의 DB 이외 다른 DB 도 복제가 되게 됩니다. 
그래서 MSR 복제 인스턴스에는 없는 데이터베이스에 대해서 Source(Master) 에서 테이블 생성이나 데이터 변경 등이 수행이 되면 그 내용이 MSR 복제 인스턴스에 반영이 되게 되고 복제 인스턴스에는 해당 DB가 없기 때문에 복제 에러가 발생되게 됩니다.

그래서 replicate-rewrite-do 와 replicate-do-db 도 같이 설정이 필요하며, replicate-do-db 에는 rewrite 된 db 명을 기재하면 됩니다. Source 서버의 원래 DB명(포스팅에서의 tdb) 을 입력하면 복제가 아에 안되게 됩니다.

위와 같이 MSR 복제 서버에서 my.cnf 에 설정 후 MySQL 서버를 재시작 하도록 하겠습니다.
재시작이 완료되었다면 MSR에서 복제 설정을 진행하도록 하겠습니다.

           

복제 설정

먼저 포스팅에서는 MSR 복제 구성 환경에서 Replication Rewrite 기능 동작을 확인하는 것을 목표로 테스트와 글이 작성되어 있습니다.

그래서 데이터 복제(mysqldump 나 xtrabackup) 후 복제 초기 구성이나 복제 전용 유저 생성 등의 과정은 진행하지 않고 바로 복제 설정을 하였고 복제 설정에서 사용하는 유저도 root 유저로 사용하였습니다.
(실제 복제 구성에서는 당연히 복제 전용 유저를 생성하여 사용하는 것이 권장됩니다.)

복제는 아래와 같이 설정 설정을 하였습니다.

-- CHANGE MASTER TO / From MySQL 8.0.23, use CHANGE REPLICATION SOURCE TO
mysql> CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='127.0.0.1'
  ,SOURCE_PORT=3306
  ,SOURCE_USER='root'
  ,SOURCE_PASSWORD='root'
  FOR CHANNEL 'ch_master1';


-- CHANGE MASTER TO / From MySQL 8.0.23, use CHANGE REPLICATION SOURCE TO
mysql> CHANGE REPLICATION SOURCE TO
  mysql > CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='127.0.0.1'
  ,SOURCE_PORT=3307
  ,SOURCE_USER='root'
  ,SOURCE_PASSWORD='root'
  FOR CHANNEL 'ch_master2';

MySQL 8.0.23 부터는 CHANGE MASTER TO 에서 CHANGE REPLICATION SOURCE TO 로 변경해서 사용하시면 됩니다.
그 외 다른 부분도 MASTER_ 라는 Prefix 대신에 SOURCE 로 변경해서 사용하시면 됩니다.

설정 후 복제 정보를 살펴보면 아래와 같이 Replicate_Rewrite_DB 정보를 확인할 수 있습니다.

mysql> show replica status\G
*************************** 1. row ***************************
< ... 중략 ... >
              Replicate_Do_DB: re_db1
< ... 중략 ... >
         Replicate_Rewrite_DB: (tdb,re_db1)
                 Channel_Name: ch_master1

*************************** 2. row ***************************
 < ... 중략 ... >
               Replicate_Do_DB: re_db2
 < ... 중략 ... >
         Replicate_Rewrite_DB: (tdb,re_db2)
                 Channel_Name: ch_master2


설정이 완료되었다면 복제를 시작합니다.

mysql> start replica;


그럼 이제 복제가 정상적으로 되는지 테스트를 해보도록 하겠습니다.

-- Replica Server(MSR)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| re_db1             |
| re_db2             |
| sys                |
| tdb                |
+--------------------+


mysql> use re_db1;

mysql> show tables;
Empty set (0.00 sec)


mysql> use re_db2;

mysql> show tables;
Empty set (0.00 sec)


일단 복제가 되는 3번째 MSR 서버에서 조회하면 위와 같은 database 에 존재하고 있으며 rewrite 대상인 DB인 re_db1 , re_db2 에 아무런 테이블이 없는 것을 확인할 수 있습니다.

Source 서버에서 아래와 같이 간단하게 테이블을 생성하면 MSR Replica 서버에서 복제가 정상적으로 되는 것을 확인할 수 있습니다.

-- Source Server 1 에서 테이블 생성
mysql> use tdb;

mysql> create table tb_test_source_1 
(col1 int primary key);



-- Replica Server 에서 테이블 생성 여부 확인
mysql> use re_db1;

mysql> show tables;
+------------------+
| Tables_in_re_db1 |
+------------------+
| tb_test_source_1 |
+------------------+

########################################

-- Source Server 2 에서 테이블 생성
mysql> use tdb;

mysql> create table tb_test_source_2 
(col1 int primary key);


-- Replica Server 에서 테이블 생성 여부 확인
mysql> use re_db2;

mysql> show tables;
+------------------+
| Tables_in_re_db2 |
+------------------+
| tb_test_source_2 |
+------------------+


1 개 이상의 rewrite rule 을 설정하고자 할 때는 아래와 같이 replicate-rewrite-do 와 replicate-do-db 를 한번씩 매칭해서 추가하면 됩니다.

replicate-do-db = ch_master1:re_db1
replicate-do-db = ch_master1:re_db3
replicate-do-db = ch_master2:re_db2


replicate-rewrite-db=ch_master1:tdb->re_db1
replicate-rewrite-db=ch_master1:tdb3->re_db3

replicate-rewrite-db=ch_master2:tdb->re_db2


간단한 과정이지만 복제 자체는 특이사항이 없는 것을 확인할 수 있습니다.


[참고] Multi Threaded Replication 관련해서 RDS 가 아닌 MySQL 엔진에서의 slave_parallel_type 와 slave_parallel_workers 시스템 변수의 변화가 있으며, MySQL 서버 8.0.26 버전 부터 replica_parallel_type 과 replica_parallel_workers 으로 이름이 변경되었습니다.

8.0.27에서는 replica_parallel_type의 기본값이 DATABASE 에서 LOGICAL_CLOCK 으로 변경되었으며, replica_parallel_workers 기본값도 4로 변경되었습니다.

8.0.29 버전부터 replica_parallel_type is deprecated 가 되고 LOGICAL_CLOCK은 이후에 독점적으로 사용된다 라고 하며 해당 부분은 8.0.29 버전이 릴리즈 되고 추가로 확인을 해보긴 해야 할 것 같습니다.

      

CHANGE REPLICATION FILTER

재시작 없이 즉시 적용하기 위해서는 다음과 같이 CHANGE REPLICATION FILTER 를 사용할 수 있으며, 복제 설정을 진행 후에 FILTER 설정을 진행하시면 됩니다.

-- 복제 설정
-- CHANGE MASTER TO / From MySQL 8.0.23, use CHANGE REPLICATION SOURCE TO
mysql> CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='127.0.0.1'
  ,SOURCE_PORT=3306
  ,SOURCE_USER='root'
  ,SOURCE_PASSWORD='root'
  FOR CHANNEL 'ch_master1';

-- CHANGE MASTER TO / From MySQL 8.0.23, use CHANGE REPLICATION SOURCE TO
mysql> CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='127.0.0.1'
  ,SOURCE_PORT=3307
  ,SOURCE_USER='root'
  ,SOURCE_PASSWORD='root'
  FOR CHANNEL 'ch_master2';


-- 복제 설정 후 FILTER 설정
mysql> CHANGE REPLICATION FILTER 
REPLICATE_DO_DB = (re_db1), 
REPLICATE_REWRITE_DB = ((tdb,re_db1))
FOR CHANNEL 'ch_master1';

mysql> CHANGE REPLICATION FILTER
REPLICATE_DO_DB = (re_db2),
REPLICATE_REWRITE_DB = ((tdb,re_db2))
FOR CHANNEL 'ch_master2';


1개 쌍(Pair) 이상으로 여러 개 설정이 필요한 경우 아래와 같이 콤마(,) 를 사용하게 되고, replicate_do_db 와 replicate_rewrite_db 모두 설정이 필요 합니다.

mysql> CHANGE REPLICATION FILTER
REPLICATE_DO_DB = (re_db1,re_db3),
REPLICATE_REWRITE_DB = ((tdb,re_db1),(tdb3,re_db3))
FOR CHANNEL 'ch_master1';


[참고] 복제가 시작된 다음 CHANGE REPLICATION FILTER 명령어를 사용하면 아래와 같이 에러 메세지가 발생됩니다.

ERROR 3085 (HY000): This operation cannot be performed with a running slave sql thread; run STOP SLAVE SQL_THREAD FOR CHANNEL 'xxx' first.

그렇기 때문에 복제 시작전에 명령어를 수행하거나, 이미 시작되어 있다면 복제를 중지한 다음 FILTER 명령어를 실행하거나 또는 채널별로 SQL_THREAD 만 중지한 다음 FILTER 명령어를 실행하고 다시 SQL_THREAD 를 재개하는 순서로 진행해야 합니다.

STOP REPLICA SQL_THREAD for channel 'xxx';

START REPLICA SQL_THREAD for channel 'xxx';



설정이 완료되었다면 아래와 같이 복제를 시작합니다.

mysql> start replica;


물론 MySQL 서버의 재시작에 대비해서 my.cnf 에 replicate-do-db  와 replicate-rewrite-db 설정에 대한 내용 추가가 필요 합니다.


이번 포스팅은 여기서 정리하도록 하겠습니다.
         

Reference

mysql.com/per-channel-replication
mysql.com/change-replication-filter


연관된 다른글

 

 

 

 

                         

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