MySQL Replication(복제) 구성 및 설정 - Semi Sync - after_sync/after_commit

Share

Last Updated on 6월 23, 2024 by Jade(정현호)

안녕하세요 
이번 포스팅은 MySQL 의 복제 구성 방법 중에 sync 방식과 버전 별 추가된 내용에 대해서 확인해보려고 합니다.  
아래 포스팅에서 이어지는 글입니다.  

           

MySQL Replication Semi Sync

Semi-sync Replication 은 MySQL 5.5 버전에서 도입된 새로운 복제 방식입니다.

Semi-sync Replication 방식은 Master 에서 Slave 로 전달된 변경 내역이 Relay log의 기록이 완료되었다는 메세지(신호)를 받고나서 처리중인 transaction의 결과를 요청한 application(client)에 결과를 반환해주는 방식 입니다.

Semi-sync Replication 방식은 Master DB에서 Slave 로 전달된 변경 내용이 Relay log의 기록이 완료되었다는 메시지(신호)를 받고나서 처리중인 transaction의 결과를 요청한 application(client)에 결과를 반환해주는 방식입니다.

<MySQL Semi-sync Replication>

Async(비동기) 방식에 비하면 Semi-sync 방식이 클라이언트에 반환되는 응답 속도 성능이 조금 저하되긴 하지만 완전한 Sync(동기화, Slave에서 relay log 내용이 DB에 적용까지 되는) 방식보다는 응답 속도 성능 저하가 덜 하고 Slave 측까지는 일단 변경 사항이 전달되었기 때문에 Master 와 Slave 사이의 데이터에 대한 동기화 나 안전성 측면에서 Async(비동기화) 방식에 비해 더욱 보장해줄 수 있게 됩니다.

Semi-sync(반동기) 복제 방식의 성능 저하는 Async(비동기) 복제에 비해 데이터 무결성을 높이는 대가입니다. 속도 저하의 정도는 최소한 커밋을 Slave로 보내고 Slave로부터 수신 확인을 기다리는 TCP/IP 왕복시간입니다.
이는 Semi-sync(반동기) 복제가 가까운 서버들 사이에서 빠른 네트워크로 통신할 때 가장 작동하며, 먼 서버들 사이에서 느린 네트워크로 통신할 때 가장 나쁘게 작동한다는 것을 의미합니다.

Semi-sync Replication 은 전달 방식에 따라서 after_commit(ver 5.5) 과 after_sync(ver 5.7.2) 방식으로 나눠지게 됩니다.
            

Semi Sync - after_commit



Semi-sync replication 은 5.5 버전에서 도입되었으며 after_commit 방식으로 처리되었습니다. 


방식은 간략하게 Commit -> Binlog Flush/Commit -> Engine Commit -> Binlog dump send Event with ACK Request -> Relay Log 에 기록 -> Ack -> User Commit OK(End) 순으로 진행 됩니다.


after_commit 은 master 에서 Engine Commit이 수행된 이후 Slave의 Relay log에 변경 사항을 기록을 하게 되고 relay log 기록 완료시 까지 User Session 은 기다리게 됩니다.
Slave의 Relay log 쓰기가 완료되면 Master에게 ACK 신호가 전달되고 User에게 Commit 완료 가 전달됩니다.

           

Semi Sync - after_sync




after_syncMySQL 5.7.2 부터 도입된 방식입니다.

Semi-Sync 동작 방식의 설정 파라미터는 rpl_semi_sync_master_wait_point 이며 사용할 Semi-Sync 방식을 정할 수 있습니다.

선택할 수 있는 값은 after_commit 또는 after_sync 이며, MySQL 5.7.2 버전 부터 after_sync 가 default 값이 되었습니다.


방식은 간략하게 Commit -> Binlog Flush/Commit -> Binlog dump send Event with ACK Request -> Relay Log 에 기록 -> Ack -> Engine Commit -> User Commit OK(End) 순으로 진행 됩니다.

after_sync 방식은 Binlog dump 을 binlog flush/commit 이후 전송하는 방식입니다.

after_commit 과의 차이가 Binlog dump 를 전송하는 시점에서 차이가 있으며 Master 서버에서 engine commit 이후 전송할 것인지(after_commit) , binlog flush/commit 이후(engine commit 전, after_sync) 에 전송할지 의 차이 입니다.


[참고] MySQL에서 바이너리 로그와 Redo Log 쓰기 관한 보다 자세한 사항은 아래 포스팅을 참조하시면 됩니다.

               

Semi sync 설정

Semi Sync 설정 전에 Async Replication 으로 설정된 상태에서 Replication을 변경하는 절차입니다.

Semi Sync 설정 전에 Replication 설정/동기화 완료 후 진행하시면 됩니다 (아래 이전글 참조)

       

플러그인 설치

semi sync는 plugin install 을 통해 설치 후 사용할 수 있습니다. master 와 slave 에 모두 아래 명령어로 plugin 을 설치합니다.

[root]# mysql --login-path=dba

   * --login-path 에 대한 내용은 해당 포스팅 를 참조하시면 됩니다.


설치(5.7 버전)

플러그인을 설치합니다.
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';


설치된 Plugin 내역을 확인합니다.

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%semi%';

+----------------------+-----------------+
|      PLUGIN_NAME        | PLUGIN_STATUS  |
+----------------------+-----------------+
| rpl_semi_sync_master   |      ACTIVE           |
| rpl_semi_sync_slave      |      ACTIVE           |
+----------------------+-----------------+


설치(8.0 버전)

MySQL 8.0.26버전 부터 기존 기존의 플로그인과 파라미터 사용은 가능하나 Deprecated 되었습니다.
향후 Removed를 고려하여 MySQL 8.0 에서는 다음의 명령어를 사용합니다.

플러그인을 설치합니다.
mysql> INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';
mysql> INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so';


설치 Plugin 내역을 확인합니다.
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_NAME LIKE '%rpl_semi_sync_%';
+-----------------------+---------------+
| PLUGIN_NAME              | PLUGIN_STATUS |
+-----------------------+---------------+
| rpl_semi_sync_replica      |        ACTIVE     |
| rpl_semi_sync_source      |        ACTIVE     |
+-----------------------+---------------+
                  

Semi sync 활성화

MySQL 5.7

semi sync 활성화 - Master/Slave 모두에서 수행
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
mysql> SET GLOBAL rpl_semi_sync_slave_enabled=1;

* 0 Disabe / 1 Enable

파라미터 설정 확인
mysql> show variables like '%rpl_semi_sync_%';


참고1) 별도의 작업을 통해서 Failover가 되거나 MHA와 같은 HA 솔루션의 Failover가 되어 Master 와 Slave 가 바뀔 경우를 대비하여 모든 DB에서 2개를 파라미터를 활성화합니다.

참고2) 관련된 파라미터로 rpl_semi_sync_master_timeout  이 있습니다.
semi sync 로 사용중에 slave 의 응답을 기다리는 최대 시간으로 default 는 10000 ms(10초) 입니다. (단위 milliseconds)
시간을 초과하게 되면 sync 에서 async 로 방식으로 복제 방식이 복귀 하게 됩니다.

슬레이브의 응답을 기다리는 최대 시간을 조금 더 낮게 조정하여 빠르게 Async 모드로 돌아오도록 조정할 수 있습니다.

슬레이브 노드가 1개 이상이라고 한다면 특정 1개의 slave의 응답 지연에 따라서 Master의 트랜잭션이 지연되지는 않습니다
한곳 이상에서 응답을 줄수 있기 때문에 Master는 지연 없이 트랜잭션 처리를 종료할 수 있습니다.

slave가 1대 라면 rpl_semi_sync_master_timeout 를 조정하는 방법이 있을 수 있으며, 또는 위와 같이 Slave를 추가하여 다른 곳에서 응답을 받을수 있는 환경을 만드는 것도 한가지 방법일 것 같습니다.


MySQL 8.0

semi sync 활성화 - Source / Replica 인스턴스 모두에서 수행
mysql> SET GLOBAL rpl_semi_sync_source_enabled = ON;
mysql> SET GLOBAL rpl_semi_sync_replica_enabled = ON;

파라미터 설정 확인
mysql> show variables like '%rpl_semi_sync_%';
                        

my.cnf 에 파라미터 추가

mysql 이 재시작 되면 기본값인 async 모드로 동작 하기 때문에 아래와 같이 my.cnf 에 파라미터를 추가해서 semi sync 모드로 동작하도록 설정이 필요 합니다.

Master, Slave 서버 모두에서 설정합니다.


MySQL 5.7

[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_slave_enabled=1

rpl_semi_sync_master_timeout=5000
   => 5000ms = 5초, 예시이며, 필수는 아닙니다.


MySQL 8.0

[mysqld]
rpl_semi_sync_source_enabled=ON
rpl_semi_sync_replica_enabled=ON
rpl_semi_sync_source_timeout=5000
                        

적용 내역 확인 및 모니터링

SHOW VARIABLES LIKE 'rpl_semi_sync%'; 와 SHOW STATUS LIKE 'Rpl_semi_sync%'; 를 통해 내역 확인 및 모니터링 할 수 있습니다.

mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';

+-------------------------------------------+-------------+
|                        Variable_name                          |     Value       |
+-------------------------------------------+-------------+
| rpl_semi_sync_master_enabled                        |       ON          |
| rpl_semi_sync_master_timeout                        |     10000      |
| rpl_semi_sync_master_trace_level                    |        32          |
| rpl_semi_sync_master_wait_for_slave_count    |         1             |
| rpl_semi_sync_master_wait_no_slave               |        ON          |
| rpl_semi_sync_master_wait_point                    | AFTER_SYNC |
| rpl_semi_sync_slave_enabled                           |      OFF          |
| rpl_semi_sync_slave_trace_level                       |       32           |
+-------------------------------------------+-------------+


• Master 
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';

+--------------------------------------------+-------+
|                           Variable_name                        |  Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients                           |     2    |
| Rpl_semi_sync_master_net_avg_wait_time         |    0     |
| Rpl_semi_sync_master_net_wait_time                |    0     |
| Rpl_semi_sync_master_net_waits                       |    0     |
| Rpl_semi_sync_master_no_times                        |    0     |
| Rpl_semi_sync_master_no_tx                             |     0    |
| Rpl_semi_sync_master_status                          |   ON   |
| Rpl_semi_sync_master_timefunc_failures          |     0    |
| Rpl_semi_sync_master_tx_avg_wait_time           |    0    |
| Rpl_semi_sync_master_tx_wait_time                  |   0     |
| Rpl_semi_sync_master_tx_waits                         |   0     |
| Rpl_semi_sync_master_wait_pos_backtraverse  |   0     |
| Rpl_semi_sync_master_wait_sessions                |   0     |
| Rpl_semi_sync_master_yes_tx                           |   0     |
| Rpl_semi_sync_slave_status                              |  OFF |
+--------------------------------------------+-------+


Slave
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';

+--------------------------------------------+-------+
| Variable_name                                                  | Value  |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients                           |    0    |
| Rpl_semi_sync_master_net_avg_wait_time         |    0    |
| Rpl_semi_sync_master_net_wait_time                |    0    |
| Rpl_semi_sync_master_net_waits                       |    0    |
| Rpl_semi_sync_master_no_times                        |    0   |
| Rpl_semi_sync_master_no_tx                              |    0   |
| Rpl_semi_sync_master_status                             | OFF |
| Rpl_semi_sync_master_timefunc_failures           |   0    |
| Rpl_semi_sync_master_tx_avg_wait_time            |   0   |
| Rpl_semi_sync_master_tx_wait_time                   |   0   |
| Rpl_semi_sync_master_tx_waits                          |   0   |
| Rpl_semi_sync_master_wait_pos_backtraverse   |   0   |
| Rpl_semi_sync_master_wait_sessions                 |   0   |
| Rpl_semi_sync_master_yes_tx                            |   0    |
| Rpl_semi_sync_slave_status                              |  ON  |
+--------------------------------------------+------+


Slave 서버에서 Semi Sync Replication 으로 동작 하는지는 Rpl_semi_sync_slave_status 값을 통해서 확인할 수 있습니다.

이미 사용중인 복제(복제 시작된 상태에서) 의 경우 "SET GLOBAL rpl_semi_sync_slave_enabled=1" 명령을 수행후에 Rpl_semi_sync_slave_status 값을 조회해보면 여전히 OFF 인 것을 확인 할 수 있습니다.


현재 수행 중인 복제에 대해서 Semi-Sync 적용은 "SET GLOBAL rpl_semi_sync_slave_enabled=1" 명령 수행 후에 복제를 중지 후 다시 시작을 한번 해줘야지 Semi-Sync 로 동작 하게 됩니다.

• 현재 복제 상태 확인 및 rpl_semi_sync_slave_enabled 활성화

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
< ... 중략 ...>
             Slave_IO_Running: Yes <!!---
            Slave_SQL_Running: Yes <!!---
-- 현재 복제가 활성화 된 상태 임


mysql> SHOW STATUS LIKE 'Rpl_semi_sync_slave_status%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF   |
+----------------------------+-------+


mysql> SET GLOBAL rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)


mysql> SHOW STATUS LIKE 'Rpl_semi_sync_slave_status%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF   |
+----------------------------+-------+

rpl_semi_sync_slave_enabled 을 변경해서 활성화하였으나 Rpl_semi_sync_slave_status 값은 여전히 OFF 입니다.

• 복제 중지 및 시작 후 다시 확인

mysql> stop slave;
mysql> start slave;


mysql> SHOW STATUS LIKE 'Rpl_semi_sync_slave_status%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+

이와 같이 현재 사용중인(활성화) 복제 또는 복제 채널에 대해서는 중지 후 다시 사직시에 Semi-Sync 가 적용되게 됩니다.

반대로 Semi-sync 에서 Async 복제로 변경시에도 복제에 대해서 중지->시작이 필요 합니다.


관련된 글(이전글) : MySQL Replication - Async 방식으로 설정



연관된 다른 글

 

 

 

 

 

 

               

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