본문 바로가기
MySQL HA & DR/Group Replication

4. Group Replication Operations

by 모모레 2017. 3. 15.

여기에서는 Group Replication의 배포 시에 어떤 모드들을 사용하는지에 대해 알아볼 것이다. 그리고 그룹 관리를 위해 일반적으로 어떤 작업을 사용하는지 알아볼 것이다.

 

1. Deploying in Multi-Primary or Single-Primary Mode

 

Group Replication은 다음과 같은 각각 다른 모드로 동작한다.

 

-- Single-primary Mode

-- Multi-Primary Mode

 

기본 모드는 Single-Primary 모드이다. 해당 그룹 내에서 다른 모드로 멤버로 배치 시킬 수는 없다. 예를 들어, 하나의 멤버는 Multi-Primary 모드 이면서 다른 하나는 Single-Primary 모드일수는 없다. 모드를 전환하려면 서버가 아닌 그룹을 다른 운영 모드로 시작해야 한다. 배포 모드에 관계없이 Group Replication은 모드가 변경될때 처리해야 해야 하는 클라이언트 측 장애 조치를 처리하지는 않는다.

 

Multi-Primary 모드가 전개되면 명령문들이 해당 모드와 호환되는지 확인하기 위해 명령문들을 체크한다. Group Replication이 Multi-Master 모드로 진행되면 다음 검사가 수행된다.

 

-- 트랜잭션의 Isolation 레벨이 SERIALIZABLE 에서 실행되고 있다면, 그룹과 동기화 될때 커밋이 실패하게 된다.

-- FK가 존재하여 같이 설정된 제약 사항이 실행되는 중이라면 해당 트랜잭션은 동기화 될때 커밋이 실패하게 된다.

 

이러한 검사는 group_replication_enforce_update_everywhere_checks 시스템 변수를 비활성화 하면 피할 수 있다. Single-Primary 모드로 배포하는 경우에는 이 옵션을 비활성화 해야 한다.

 

1.1 Single-Primary Mode

 Single-Primary Mode로 설정된 Group Replication에서는 하나의 서버만 읽기/쓰기가 가능한 서버이다.  자동적으로 다른 모든 서버는 읽기만 가능한 서버로 설정된다. 읽기/쓰기가 가능한 서버는 기본적으로 가장 처음에 추가된 서버가 설정되고, 그 이후에 추가된 서버들은 읽기용 서버가 된다. 


Single-Primary 모드에서 Multi-Primary 모드에서 시행되어야 하는 검사중 일부는 비활성화된다. 이는 하나의 구성안에서 한대의 서버에서만 DML 작업이 실행되기 때문에 가능한 것이다. 또한, Single-Primary 모드에서는 FK를 가진 테이블에 대한 변경 작업이 가능하지만, Multi-Primary 모드에서는 해당 테이블에 대한 변경이 불가능 하다. 

만약, Primary 서버에 문제가 발생하여 Fail이 발생하면, 자동적으로 Primary 서버로 승격하기 위한 투표가 이루어져 Primary 서버를 변경하는 작업을 진행한다. 이때, UUID를 기준으로 하여 정렬을 통해 논리적으로 순서를 정하여 이때 선택된 첫번째 서버가 다음 Primary 서버가 된다. 


이와 같은 작업이 진행 중일때에 클라이언트쪽 어플리케이션들은 re-routing 작업을 하기 전에 Group Replication내의 작업이 완료 되고, 모든 변경 내역이 새로운 Primary 서버에 적용된 것을 기다리는 것이 좋다. 


1.2 Multi-Primary Mode 

Multi-Primary 모드에서는 Primary 서버의 개념이 없다. 그래서 Primary 서버를 선택하기 위한 투표 프로세스가 존재하지 않는다. 


즉, 그룹 내의 모든 서버는 읽기/쓰기가 가능한 상태가 된다. 


1.3 Finding the Primary 


다음의 예는 Single-Primary 모드에서 Primary 서버가 어떤 서버인지 찾는 방법을 말한다. 


mysql> SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member';

+--------------------------------------+

| VARIABLE_VALUE                       |

+--------------------------------------+

| 69e1a3b8-8397-11e6-8e67-bf68cbc061a4 |

+--------------------------------------+

1 row in set (0,00 sec)

 

2. Tuning Recovery


새로운 서버가 Group Replication에 추가되면 해당 데이터를 넘겨줄 적절한 서버를 선택하게 된다. 그리고, 데이터를 온전히 다 가져가서 ONLINE상태가 될 수 있을 때 까지 데이터들을 가져오게 된다. Group Replication의 중요한 사항은 fault tolerant와 configurable에 있다. 여기에서는 복구 작업을 어떻게 하는지에 대한 것과 설정을 어떻게 최적화 하는지에 대해 알아보도록 한다. 


2.1 Donor Selection


Random Donor 방식으로 그룹 안에서 존재하는 온라인 상태의 서버중 하나를 선택할 수 있다. 이와 같은 방식으로 선택하게 되면 그룹 내에서 같은 서버를 두번 이상 선택하지 않을 가능성이 있다. 


Random Donor 방식으로 선택한 서버에 접근하지 못하게 된ㄴ 경우 새로운 Donor를 선택하게 되고, 복구하려는 서버는 해당 서버에 자동으로 연결을 시도한다. 만약, 연결 재시도작업이 임계치를 넘어가게 되면 복구 작업은 실패로 귀결된다. 


Donor는 Current View를 통해 온라인 상태의 서버중에 임의로 선택된다.


2.2 Enhanced Automatic Donor Switchover


복구 작업을 진행할 때 중요한 것은 복구 작업 시 발생하는 실패에 대처하는 것이다. 따라서, Group Replication은 강력한 오류 감지 메커니즘을 가지고있다. 이전 버젼에서는 인증 문제 및 연결 오류만 감지할 수 있었다. 인증 문제및 연결 오류를 감지하면 새로운 Donor를 찾아서 재 연결 하는 방식으로 오류를 해결했다. 


현재 버젼에서는 다음과 같은 내용이 포함되었다. 


-- Purged Data Scenarios : 선택한 Donor에 복구작업에 필요한 데이터가 삭제되고 없다면 오류가 발생하게 구현되어있다. 이런 경우 오류를 감지하고 새로운 Donor를 선택하여 처리하게 한다. 


-- Duplicate Data : 복구 작업을 진행하는 도중에 Duplicate가 발생하게 되면 오류를 발생하게 한다. 이런 경우는 잘못된 트랜잭션(errant transactions present in the joiner)으로 인해 발생할 수도 있다.  


-- Other errors : 복구 스레드 중 하나라도 실패하게 되면 오류가 발생하고 복구작업은 다른 Donor를 선택하여 다시 시작하게 된다. 


일부 지속적인 또는 일시적인 장애가 발생하는 경우 복구 작업은 새로운 Donor를 선택하여 다시 연결하여 시도하게 된다. 


2.3 Donor Connection Retries 


복구 데이터를 전송하는 작업은 바이너리 로그와 기존의 MySQL Replication 을 이용하여 진행되기 때문에 일부 일시적인 오류로 인해 오류가 발생할 수 있다. 이러한 경우 Donor 전환 프로세스에는 일반 MySQL Replication에서와 유사한 재접속 시도 기능이 있다. 


2.4 Number of Attempts


복구를 진행해야 하는 서버가 Donor의 연결을 시도하는 횟수는 10번이다. 이 값은 시스템 변수 group_replication_recovery_count를 통해 설정된다. 다음 명령과 같이 설정값을 수정할 수 있다. 


SET GLOBAL group_replication_recovery_retry_count= 10;


2.4 Sleep Routines 


group_replication_recovery_reconnect_interval 시스템 변수는 복구 프로세스가 Donor에 연결을 재시도할 때 중간에 얼마나 쉬고 다시 시도할 것인지를 설정하는 변수이다. 이 변수의 기본값은 60초이고, 동적으로 변경이 가능하다. 다음과 같이 사용이 가능하다. 


SET GLOBAL group_replication_recovery_reconnect_interval= 120;


복구 작업은 모든 서버에 접속을 시도하는 중에는 Sleep 상태에 빠지지 않는다. 하나의 서버에 접속을 시도할 때 발생한 문제가 다른 서버에서도 동일하게 발생하리라는 보장이 없기 때문이다. 그래서 모든 서버에 한번씩 다 시도해 보고 나서도 제대로 연결이 되지 않는다면 그 때 group_replication_recovery_interval 변수에 설정된 시간 만큼 Sleep 상태에 빠지게 된다. 


3. Network Partitioning


Group Replication은 Replication 작업과 관련하여 변경 사항이 있을때 마다 모든 구성 서버들의 합의를 거쳐서 진행해야 할 필요가 있다. 일반적인 트랜잭션에 관련된 것 뿐만 아니라 그룹내의 서버들의 어떤 변경 및 일부 그룹의 일관선 유지를 위한 내부 메세징에 대해서도 합의가 필요할 수 있다. 만약, 그룹내의 서버들이 대부분 유실되서 과반수를 넘는 합의를 진행할 수 없다면 해당 작업을 진행할 수 없다. 


갑자기 여러 서버에서 문제가 발생하여 합의 진행시 과반수가 넘는 결정을 받을 수 없게 될 수 있다. 즉, 5대의 서버로 구성된 Group Replication에서 한번에 3대가 침묵하는 상황이 발생가헤 된다면 과반수의 결정값을 받을 수 없게 된다. 그래서 이런 경우에는 어떤 상황인지 파악하기 어렵기 때문에 그룹을 자동으로 재구성할 수 없게 된다. 


하지만, 서버 한대가 자발적으로 제거되는 경우라는 그룹을 재구성하게 지시할 수 잇다. 즉, 이와 같은 경우는 구성 서버 한 대가 다른 서버들에게 자신의 퇴장을 알리는 메세지를 보냄으로서 가능하게 된다. 그래서 다른 구성 서버들이 그룹을 적졀히 재구성할 수 있게 되고 그 구성원의 일관성이 유지될 수 있게 되는것이다. 즉, 위의 시나리오에 따라 보면 5대의 서버중 3대가 모두 탈퇴한다는 메세지를 보내고 나가게 되면, 자동으로 멤버가 5에서 2로 가는 재구성 작업이 일어날 수 있다. 물론 이런 일이 일어나는 동안에도 정족수에 따른 결과값을 확보해야 한다. 



3.1 Detecting Partitions 

Performance_schema에 있는 replication_group_members 테이블은 해당 서버에서 가지고 있는 current view 정보에 기반한 각 서버의 상태 정보를 보여준다. 대부분 시스템이 분할되어있지 않으므로 테이블에 그룹의 모든 서버들은 일관된 정보를 보여주게 된다. 즉, 하나의 그룹안의 모든 서버의 정보가 동일한 정보를 가지고 있는 것이다. 그러나, 네트워크 분할이 발생하여 그룹이 나뉘어지게 되면 해당 테이블의 정보는 각 서버마다 다른 정보를 가지게 된다. 그리고 각 서버별로 정보를 알 수 없는 서버들은 UNREACHABLE 상태로 보여지게 된다. 해당 정보는 Group Replication에 내장된 로컬 실패 감지기를 통해 내보내진다. 





위 유형의 네트워크 단절 시 발생하는 문제를 이해하기 위해 발생하는 시나리오를 설명하려 합니다. 다음과 같이 5개의 id를 가진 서버가 있다고 가정합니다. 


-- 서버 1번 : 199b2df7-4aaf-11e6-bb16-28b2bd168d07

-- 서버 2번: 199bb88e-4aaf-11e6-babe-28b2bd168d07

-- 서버 3번: 1999b9fb-4aaf-11e6-bb54-28b2bd168d07

-- 서버 4번: 19ab72fc-4aaf-11e6-bb51-28b2bd168d07

-- 서버 5번: 19b33846-4aaf-11e6-ba81-28b2bd168d07


Group Replication으로 구축한 후, 장애 없이 5개의 서버가 모두 ONLINE 상태로 잘 운영되고 있다. 이런 경우 S1에 접속하여 replication_group_members 테이블을 확인하면 다음과 같이 확인됨을 알 수 있다. 


mysql> SELECT * FROM performance_schema.replication_group_members;

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| group_replication_applier | 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | 127.0.0.1   |       13002 | ONLINE       |

| group_replication_applier | 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | 127.0.0.1   |       13001 | ONLINE       |

| group_replication_applier | 199bb88e-4aaf-11e6-babe-28b2bd168d07 | 127.0.0.1   |       13000 | ONLINE       |

| group_replication_applier | 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | 127.0.0.1   |       13003 | ONLINE       |

| group_replication_applier | 19b33846-4aaf-11e6-ba81-28b2bd168d07 | 127.0.0.1   |       13004 | ONLINE       |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

5 rows in set (0,00 sec)



이후에 치명적인 문제가 발생하여 S3, S4, S5가 예기치 않게 중지된다고 가정하자. 그렇게 되면, 몇 초 후에 S1의 replication_group_members 테이블에는 다음과 같이 해당 서버들이 UNREACHABLE로 표시됨을 알 수 있다. 이런 경우 해당 구성은 멤버쉽 정보 변경을 위한 재구성 작업을 할 수가 없다. 대다수가 손실되었기 때문이다. 


mysql> SELECT * FROM performance_schema.replication_group_members;

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| group_replication_applier | 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | 127.0.0.1   |       13002 | UNREACHABLE  |

| group_replication_applier | 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | 127.0.0.1   |       13001 | ONLINE       |

| group_replication_applier | 199bb88e-4aaf-11e6-babe-28b2bd168d07 | 127.0.0.1   |       13000 | ONLINE       |

| group_replication_applier | 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | 127.0.0.1   |       13003 | UNREACHABLE  |

| group_replication_applier | 19b33846-4aaf-11e6-ba81-28b2bd168d07 | 127.0.0.1   |       13004 | UNREACHABLE  |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

5 rows in set (0,00 sec)


이와 같이 다수가 장애로 인해 접근할 수 없는 상태에 빠지면 외부의 도움 없이 자동으로 시스템을 재 구성하는 것이 불가능하다. 이 경우 시스템을 재구성 할 수 있도록 구성원 목록을 재설정해야 한다. 



3.2 Unblocking a Partition 

Group Replication을 사용자가 직접 특정 구성을 강제로 변경하여 Group 내의 구성원 목록을 수정하는 것이 가능하다. 이를 위해서는 구성원에 대한 정보를 확인한 다음 group_replication_force_members 변수를 사용해야 한다. 


S1과 S2가 그룹에 남아있는 유일한 상태인 경우로 돌아가서 보면, 서버 S3, S4, S5가 장애로 빠짐으로 인해 재구성을 자동으로 못하는 상황에 놓인 것을 확인할 수 있다. 이때, 서버 S1과 S2를 계속 사용하고 싶다면, S1과 S2만 포함하는 멤버쉽을 구성하면 된다. 


이 방법은 마지막 수단으로만 사용되어야 한다. group_replication_force_members 를 사용한다는 것은 굉장히 위험한 일이기 때문이다. 


현재 장애 상황이 다음과 같음을 확인한다. (S1 의 로컬 장애 감지기에 의해 감지됨)

mysql> SELECT * FROM performance_schema.replication_group_members;

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| group_replication_applier | 1999b9fb-4aaf-11e6-bb54-28b2bd168d07 | 127.0.0.1   |       13002 | UNREACHABLE  |

| group_replication_applier | 199b2df7-4aaf-11e6-bb16-28b2bd168d07 | 127.0.0.1   |       13001 | ONLINE       |

| group_replication_applier | 199bb88e-4aaf-11e6-babe-28b2bd168d07 | 127.0.0.1   |       13000 | ONLINE       |

| group_replication_applier | 19ab72fc-4aaf-11e6-bb51-28b2bd168d07 | 127.0.0.1   |       13003 | UNREACHABLE  |

| group_replication_applier | 19b33846-4aaf-11e6-ba81-28b2bd168d07 | 127.0.0.1   |       13004 | UNREACHABLE  |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

5 rows in set (0,00 sec)


가장 먼저 할일은 S1과 S2의 물리 id( 통신 주소)를 확인하는 것이다. S1과 S2에 접속하여 다음과 같이 해당 정보를 확인한다. 


mysql> SELECT @@group_replication_local_address;

+-----------------------------------+

| @@group_replication_local_address |

+-----------------------------------+

| 127.0.0.1:10000                   |

+-----------------------------------+

1 row in set (0,00 sec)



mysql> SELECT @@group_replication_local_address;

+-----------------------------------+

| @@group_replication_local_address |

+-----------------------------------+

| 127.0.0.1:10001                   |

+-----------------------------------+

1 row in set (0,00 sec)


위와 같이 확인한 통신 주소를 가지고 새롭게 재구성하도록 한다. S1에서 다음과 같이 실행한다. 이렇게 기입하면, 이 정보가 기존 정보보다 높은 우선순위를 가진다. 


mysql> SET GLOBAL group_replication_force_members="127.0.0.1:10000,127.0.0.1:10001";

Query OK, 0 rows affected (7,13 sec)


위와 같이 하면 다른 구성으로 강제적으로 변경되어 그룹의 차단을 해제할 수 있다. 이와 같이 변경 한 후 S1과 S2에서 replication_group_members 를 확인해 본다. 


mysql> select * from performance_schema.replication_group_members;

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| group_replication_applier | b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | 127.0.0.1   |       13000 | ONLINE       |

| group_replication_applier | b60907e7-4ab6-11e6-afb7-28b2bd168d07 | 127.0.0.1   |       13001 | ONLINE       |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

2 rows in set (0,00 sec)



mysql> select * from performance_schema.replication_group_members;

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

| group_replication_applier | b5ffe505-4ab6-11e6-b04b-28b2bd168d07 | 127.0.0.1   |       13000 | ONLINE       |

| group_replication_applier | b60907e7-4ab6-11e6-afb7-28b2bd168d07 | 127.0.0.1   |       13001 | ONLINE       |

+---------------------------+--------------------------------------+-------------+-------------+--------------+

2 rows in set (0,00 sec)



이와 같이 강제로 구성 변경을 하기 전에 실제 장애로 판명된 서버들이 실제 장애인지 아닌지 확인하는게 중요하다. S3, S4, S5가 실제 장애일 수도 있지만, 단순한 네트워크 단절로 인해 3개가 자체적으로 자동 재구성으로 하나의 셋트를 구성했을 수도 있다. 이 경우 S1, S2를 강제 재구성을 하면 split-brain 상황이 되어 버리기 때문에 문제가 될 수 있다. 






'MySQL HA & DR > Group Replication' 카테고리의 다른 글

6. Group Replication System Variables  (0) 2017.03.23
5. Group Replication Security  (0) 2017.03.21
3. Monitoring Group Replication  (0) 2017.03.13
2. Getting Started  (0) 2017.02.28
1. Group Replication Background  (0) 2017.02.22