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

Last Updated on 2월 15, 2021 by 태랑(정현호)



Mysql replication Semi Sync



Semi-sync Replication은 Mysql 5.5 버전에서 도입된 sync 형태의 복제 방식 입니다.


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



Async 방식에 비하면 성능이 조금 저하되긴 하지만 완전한 sync(slave에서 relay log 내용까지 적용되는) 방식보다는 성능 저하가 덜 하고 Slave 까지는 일단 변경이력이 전달 되었기 때문에 Master와 slave 사이의 데이터에 대한 동기화 나 안전성 측면에서 async 방식에 비해 더욱 보장해줄 수 있습니다.


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_sync 는 mysql 5.7.2 부터 도입된 방식 입니다.
관련 파라미터는 rpl_semi_sync_master_wait_point 로 설정을 통해 사용할 방식을 정할 수 있습니다( after_commit or after_sync )
default value 는 5.7.2 부터 after_sync   입니다.

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

after_commit 과의 차이가 Binlog dump 를 전송하는 시점이 master 서버에서 engine commit 이후 전송 할 것인지, binlog flush/commit 이후(engine commit전) 에 전송 할지에서 차이를 보이게 됩니다.



Semi sync 설정


* Semi Sync 설정 전에 Async Replication 으로 설정된 상태에서 Replication을 변경 하는 절차 입니다.
Semi Sync 설정 전에 Replication 설정/동기화 완료 후 진행하시면 됩니다 (아래 이전글 참조)




# Plugin 설치
semi sync는 plugin install 을 통해 설치 후 사용 할 수 있습니다.

master 와 slave 에 모두 아래 명령어로 plugin 을 설치 합니다.


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

   * --login-path 에 대한 내용은 하단의 연관된 포스트를 참조하시면 됩니다.


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 |
+----------------------+---------------+



# semi sync 활성화 - Master 에서 수행
SET GLOBAL rpl_semi_sync_master_enabled = 1;

# Semi Sync 활성화 - Slave 에서 수행
SET GLOBAL rpl_semi_sync_slave_enabled=1;

* 0 Disabe / 1 Enable


참고) 관련된 파라미터로 SET GLOBAL 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를 추가하여 다른곳에서 응답을 줄수 있는 환경을 만드는 것도 한가지 방법일 것 같습니다.



my.cnf 에 파라미터 추가


mysql 이 재시작 되면 기본인 async 모드로 동작 하기 때문에 아래와 같이 my.cnf 에 파라미터를 추가해 줘야 합니다.


# Master 에 설정
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=5000
   => 5000ms = 5초, 예시 입니다 


# Slave 노드 모든 곳에서 설정

[mysqld]
rpl_semi_sync_slave_enabled=1



적용 내역 확인 및 모니터


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 |
+--------------------------------------------+-------+



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



연관된 글
mysql --login-path 사용하여 접속

Workbench(워크벤치) - Cloud 환경 등에서 SSH Key 를 이용한 Mysql 접속

Mysql CTAS/Insert Select 에서 공유락(Shared Lock) 문제

답글 남기기