Skip to content
난이도 문제은행 3

그룹 복제와 InnoDB 클러스터 4 ​

그룹 복제(Group Replication)를 운영하면 두 가지를 정해 두어야 한다. 하나는 쓰기를 받는 프라이머리(primary)의 변경을 받아 적용하는 세컨더리(secondary)에서 읽을 때, 방금 쓴 값이 보이기를 얼마나 기다릴지이고, 다른 하나는 과반수인 정족수(quorum)를 잃어 그룹이 멈췄을 때 어떻게 되살릴지다. 구성과 요구사항은 그룹 복제와 InnoDB 클러스터 3에서 다뤘다.

읽기 일관성 수준 ​

그룹 복제에서 커밋(commit) 응답은 그룹이 트랜잭션(transaction) 순서를 합의하고 충돌 검사(certification)를 통과했다는 뜻이고, 다른 멤버가 이미 적용했다는 뜻은 아니다. 그래서 세컨더리에서 읽으면 방금 쓴 값이 아직 안 보일 수 있다. group_replication_consistency로 이 기다림을 얼마나 할지 정한다. 전역으로도, 세션별로도 바꿀 수 있다.

값동작
EVENTUAL아무것도 기다리지 않는다(8.0 기본)
BEFORE_ON_PRIMARY_FAILOVER새 프라이머리가 밀린 변경을 다 적용할 때까지 새 트랜잭션을 붙잡는다(8.4 기본)
BEFORE트랜잭션 시작 전에 앞선 트랜잭션이 이 멤버에 다 적용되길 기다린다
AFTER쓰기 트랜잭션이 모든 멤버에 적용될 때까지 커밋 응답을 늦춘다
BEFORE_AND_AFTER둘 다

장애 조치(failover) 직후의 새 프라이머리는 옛 프라이머리의 변경을 아직 다 적용하지 못했을 수 있어, 곧바로 읽고 쓰면 옛 값을 보게 된다. BEFORE_ON_PRIMARY_FAILOVER는 이 짧은 구간만 막으므로 평소에는 비용이 없다.

BEFORE는 읽는 쪽이 비용을 내고 최신 값을 보는 방식이고, AFTER는 쓰는 쪽이 비용을 내서 이후 어느 멤버에서 읽어도 최신 값이 보이게 하는 방식이다. 읽기가 대부분이고 쓰기가 드문 그룹이면 AFTER가, 쓰기가 많으면 필요한 읽기 세션에만 BEFORE를 거는 편이 유리하다. 일반 비동기 복제(asynchronous replication)에서 같은 문제를 다루는 방법은 복제 토폴로지와 고급 설정 2에 있다.

정족수를 잃었을 때 ​

그룹은 과반수가 모여야 결정을 내린다. 5대 중 3대가 한꺼번에 응답하지 않으면, 남은 2대는 나머지 3대가 죽은 것인지 네트워크 분할(network partition)로 자기들만 고립된 것인지 구별할 수 없다. 그래서 남은 쪽은 쓰기를 멈추고 기다린다. 이것이 정족수 손실이다. 반대로 멤버가 스스로 그룹을 떠나면 떠난다고 알리므로 그룹이 과반수를 다시 계산해 계속 일한다.

사람이 판단해 되살리는 방법은 이렇다.

  1. Performance 스키마(Performance Schema)의 replication_group_members 테이블에서 어떤 멤버가 ONLINE이고 어떤 멤버가 UNREACHABLE인지 본다.
  2. 연락이 안 되는 멤버가 정말로 멈췄는지 확인한다. 살아서 쓰기를 받고 있다면 강제로 그룹을 만들면 스플릿 브레인(split brain)이 된다.
  3. 남은 멤버 하나에서 group_replication_force_members에 남은 멤버들의 주소를 넣어 멤버 구성을 강제로 정한다. 그룹이 풀리면 이 값을 다시 빈 값으로 되돌린다. InnoDB 클러스터에서는 관리 도구 MySQL Shell의 cluster.forceQuorumUsingPartitionOf()가 같은 일을 한다.
  4. 모든 멤버가 한꺼번에 내려갔다면 dba.rebootClusterFromCompleteOutage()로 가장 최신 멤버를 기준으로 클러스터를 다시 띄운다.

싱글 프라이머리 모드(single-primary mode)로 도는 그룹에서 프라이머리가 소수 쪽에 남았다면, 다른 멤버에 없는 트랜잭션을 들고 있을 수 있다. 그 멤버는 그룹과 데이터가 갈라진 상태라 그대로는 다시 들어올 수 없고 오류를 낸다. 보통은 남는 트랜잭션을 확인해 따로 처리한 뒤, 그 멤버를 다른 멤버의 데이터로 새로 채워 넣는다. 강제 복구는 최후의 수단이다. 멤버가 2f + 1대면 f대 장애까지 견디고 4대는 3대와 똑같이 1대 장애만 견디므로, 애초에 예상 장애 수에 맞춰 멤버 수를 홀수로 잡는 것이 먼저다.

면접 포인트 ​

  • "세컨더리에서 방금 쓴 값이 안 보여요" → 커밋은 합의·충돌 검사 통과까지만. group_replication_consistency를 BEFORE나 AFTER로.
  • "8.4의 일관성 기본값은?" → BEFORE_ON_PRIMARY_FAILOVER. 새 프라이머리가 밀린 변경을 다 적용할 때까지만 새 트랜잭션을 붙잡는다(8.0은 EVENTUAL).
  • "5대 중 3대가 끊기면?" → 남은 2대는 과반수가 없어 멈춘다. 끊긴 쪽이 정말 멈췄는지 확인 후 force_members나 forceQuorumUsingPartitionOf()로 강제 복구.

관련 문서