LLM WikiAccess-protected knowledge portal
← 스터디 홈
153편 · 약 13분

MySQL Group Replication과 InnoDB Cluster: Paxos 쿼럼 메커니즘과 통신 스택 변화 (MySQL 26.7)

요약

MySQL Group Replication은 Paxos 기반 합의 프로토콜로 멀버 간 쓰기 순서를 결정하고, 과반 쿼럼이 살아 있는 한 자동으로 프라이머리를 선출한다. 이 위에 MySQL Shell의 어드민 API와 MySQL Router의 클라이언트 라우팅을 더한 것이 InnoDB Cluster다.

MySQL 26.7(2026년 7월 캘린더 버전)에서 가장 눈에 띄는 운영 변화는 group_replication_communication_stack의 기본값이 XCOM에서 MYSQL로 바뀐 것이다. MYSQL 스택은 별도의 XCom 전용 포트(기본 33061) 없이 표준 MySQL 연결 보안(caching_sha2_password, TLS)을 그대로 사용한다. 기존 클러스터를 업그레이드하거나 새 클러스터를 구성할 때 이 변화를 인식하지 못하면 멤버 조인이 실패하거나 방화벽 규칙이 어긋날 수 있다.

이 글은 Group Replication의 합의 구조부터 단일-프라이머리·멀티-프라이머리 운영 패턴, 쿼럼 손실 복구, MySQL Router의 역할까지 실제 운영에 필요한 내용을 다룬다.


Group Replication의 합의 구조

Paxos 위의 XCom

Group Replication은 XCom(eXternal Communication)이라는 Paxos 변형 라이브러리를 내부적으로 사용한다. XCom은 멤버 간에 메시지 순서를 합의하는 역할을 한다.

클라이언트가 트랜잭션을 커밋하면:

  1. 프라이머리 노드가 트랜잭션의 write set(변경된 행의 기본 키 해시 집합)을 그룹 전체로 브로드캐스트한다.
  2. 모든 살아있는 멤버가 수신을 확인(ACK)한다.
  3. 과반 이상의 ACK가 모이면 해당 트랜잭션이 커밋 순서로 확정된다.
  4. 각 멤버는 확정된 순서대로 트랜잭션을 로컬에 적용한다.

이 과정에서 충돌 감지가 일어난다. 두 트랜잭션이 같은 행을 동시에 수정했다면, 먼저 커밋된 것만 살아남고 나머지는 롤백된다. 단일-프라이머리 모드에서는 쓰기가 프라이머리에만 허용되므로 충돌이 구조적으로 발생하지 않는다. 멀티-프라이머리 모드에서는 충돌 감지가 핵심 경로가 된다.

쿼럼과 내결함성

Group Replication은 과반 쿼럼을 요구한다. N개의 멤버로 구성된 그룹이 정상 동작하려면 적어도 ⌊N/2⌋+1개의 멤버가 살아 있어야 한다.

멤버 수허용 실패 수
31
52
73

3개 멤버 클러스터가 가장 많이 쓰이는 이유가 여기 있다. 1개 실패를 허용하면서 비용을 최소화할 수 있는 최소 구성이기 때문이다. 짝수 멤버 구성(2, 4개)은 피하는 것이 일반적이다. 2개 클러스터에서 1개가 실패하면 쿼럼을 잃어 그룹이 읽기 전용이 된다.


통신 스택: XCOM vs MYSQL

XCOM 스택의 구조

XCOM 스택(MySQL 8.0.27 이전 기본값)에서는 Group Replication이 XCom 전용 TCP 포트를 사용한다. 기본값은 33061이며, group_replication_local_address 설정으로 지정한다.

SET GLOBAL group_replication_local_address = '10.0.0.1:33061';

이 포트로 그룹 내부 메시지가 오가므로, 방화벽에서 모든 노드 간 33061 포트를 열어야 한다. 인증은 XCom 자체 메커니즘을 사용하며, MySQL 사용자 인증과는 독립적으로 동작한다.

MYSQL 스택의 구조

MySQL 26.7에서 기본이 된 MYSQL 스택은 XCom 전용 포트를 없앤다. 대신 MySQL 표준 포트(3306 또는 X 프로토콜 포트 33060)를 통해 그룹 통신을 수행한다.

SET GLOBAL group_replication_communication_stack = 'MYSQL';

MYSQL 스택의 변화는 세 가지다.

첫째, 방화벽 단순화. 33061 포트를 따로 열 필요가 없다. 이미 MySQL 표준 포트가 열려 있다면 추가 규칙 없이 그룹 통신이 작동한다.

둘째, 인증 통합. group_replication_ssl_mode, caching_sha2_password, TLS 인증서가 그룹 통신에도 그대로 적용된다. 별도의 XCom 인증 설정이 필요 없다.

셋째, Recovery 연결 재사용. 멤버 복구(distributed recovery) 시 사용되는 연결도 동일한 MySQL 연결 경로를 따른다.

기존 클러스터 마이그레이션

XCOM → MYSQL 스택 전환은 순차적인 재시작이 필요하다. 롤링 재시작으로 진행하되, 스택을 혼용한 채로 그룹을 운영할 수 없다는 점을 주의해야 한다.

-- 1. 각 멤버에서 그룹 복제 중지
STOP GROUP_REPLICATION;

-- 2. 통신 스택 변경 (my.cnf에도 반영)
SET PERSIST group_replication_communication_stack = 'MYSQL';

-- 3. 그룹 복제 재시작
START GROUP_REPLICATION;

모든 멤버를 MYSQL 스택으로 전환한 후에야 그룹이 정상 동작한다. 중간 상태에서 XCOM 멤버와 MYSQL 멤버가 혼재하면 조인이 실패한다.


MySQL InnoDB Cluster 구조 애플리케이션 (Read/Write) 애플리케이션 (Read Only) MySQL Router 6446 (R/W) → Primary | 6447 (RO) → Secondary MySQL Shell dba.createCluster() cluster.addInstance() / status() Group Replication 클러스터 (Paxos 쿼럼) Primary Read/Write binlog + relay log group_replication _applier (local) XCOM or MYSQL stack Secondary 1 Read Only relay log 적용 자동 Failover 대상 (선출 우선순위 설정 가능) Secondary 2 Read Only relay log 적용 쿼럼 유지 역할 (최소 3노드 필요) Paxos Paxos Paxos 그룹 통신 (MYSQL 스택: 표준 3306 포트 사용) MySQL Router → 노드 연결 (R/W: 6446, RO: 6447)
MySQL InnoDB Cluster 아키텍처: Group Replication + MySQL Router + MySQL Shell

단일 프라이머리 vs 멀티 프라이머리

단일 프라이머리 (권장)

기본 모드다. 한 번에 하나의 멤버만 쓰기를 허용하고, 나머지는 읽기 전용이다. 쓰기 충돌이 구조적으로 발생하지 않아 운영이 단순하다.

프라이머리가 실패하면 그룹이 자동으로 새 프라이머리를 선출한다. 선출 기준은 group_replication_member_weight(기본값 50) 값이 높은 멤버를 우선한다. 같은 가중치면 UUID 사전순으로 결정된다.

-- 특정 멤버를 우선 선출 대상으로 설정
SET PERSIST group_replication_member_weight = 80;

MySQL Shell에서는 한 줄로 프라이머리 전환이 가능하다.

cluster.setPrimaryInstance('mysql://10.0.0.2:3306')

멀티 프라이머리

모든 멤버가 읽기-쓰기를 허용한다. 모든 노드에 쓸 수 있어 부하 분산에 유리하지만, 운영 복잡성이 높아진다. 같은 행을 두 노드가 동시에 수정하면 낙관적 잠금(Optimistic Locking)으로 충돌을 감지하고 한쪽을 롤백한다.

일반 OLTP 애플리케이션에서는 단일 프라이머리를 권장한다. 멀티 프라이머리는 지리적으로 분산된 쓰기가 명확히 필요하고, 애플리케이션이 충돌 재시도를 처리할 수 있는 경우에만 고려한다.


InnoDB Cluster 운영 패턴

클러스터 초기 구성

MySQL Shell을 사용해 클러스터를 구성한다.

// MySQL Shell에서
const cluster = dba.createCluster('myCluster');
cluster.addInstance('mysql://10.0.0.2:3306');
cluster.addInstance('mysql://10.0.0.3:3306');
cluster.status();

cluster.status()는 각 멤버의 상태, 프라이머리 여부, 복제 지연을 한눈에 보여준다.

MySQL Router 자동 구성

MySQL Router는 클러스터 메타데이터(InnoDB ClusterSet 메타데이터 스키마)를 읽고 자동으로 라우팅 규칙을 설정한다.

mysqlrouter --bootstrap mysql://[email protected]:3306 \
            --directory /var/lib/mysqlrouter \
            --user mysqlrouter

이 명령 한 번으로 다음 포트가 열린다.

포트용도
6446고전 MySQL 프로토콜, 읽기-쓰기 (Primary로 라우팅)
6447고전 MySQL 프로토콜, 읽기 전용 (Secondary로 라우팅)
6448X 프로토콜, 읽기-쓰기
6449X 프로토콜, 읽기 전용

프라이머리 전환이 일어나면 Router가 메타데이터를 다시 읽어 자동으로 연결을 새 프라이머리로 전환한다. 애플리케이션은 Router 주소만 바라보면 된다.

쿼럼 손실과 복구

과반 미만의 멤버만 남으면 그룹은 쿼럼을 잃고 읽기 전용이 된다. 3개 클러스터에서 2개가 동시에 실패한 경우가 여기에 해당한다.

네트워크 파티션이 아닌 실제 장애임이 확인되면, 살아남은 멤버에서 쿼럼을 강제로 재구성할 수 있다.

// MySQL Shell에서 (주의: 데이터 손실 가능)
cluster.forceQuorumUsingPartitionOf('mysql://10.0.0.3:3306');

이 명령은 지정한 멤버가 속한 파티션의 멤버만으로 새 쿼럼을 구성한다. 다른 파티션에 있던 멤버는 그룹에서 제외된다. 반드시 단일 데이터센터 장애임을 확인한 후 실행해야 한다. 네트워크 분리(split-brain) 상황에서 양쪽에서 모두 실행하면 데이터 불일치가 발생한다.

복구 후에는 제외된 멤버를 클러스터에 다시 조인한다.

cluster.rejoinInstance('mysql://10.0.0.1:3306');

MySQL 26.7 업그레이드 체크리스트

MySQL 26.7로 업그레이드하거나 새 클러스터를 구성할 때 확인할 사항을 정리했다.

통신 스택 관련

  • 기존 클러스터가 XCOM을 쓴다면 업그레이드 전에 MYSQL 스택 전환 계획을 세워라.
  • 33061 포트 방화벽 규칙을 제거하고 3306/33060이 노드 간에 열려 있는지 확인하라.
  • group_replication_ip_allowlist 대신 MySQL 사용자 인증 + TLS로 접근을 제어한다.

MySQL Shell 버전

  • InnoDB Cluster 운영에 사용하는 MySQL Shell 버전이 서버 버전과 일치하거나 최신인지 확인하라. Shell과 서버 버전 불일치는 어드민 API 오류를 유발할 수 있다.

MySQL Router 재부트스트랩

  • 서버 업그레이드 후 Router를 재부트스트랩하면 새 메타데이터 스키마를 반영한다.
mysqlrouter --bootstrap mysql://[email protected]:3306 \
            --directory /var/lib/mysqlrouter \
            --force

Open question: MySQL 26.7에서 MYSQL 스택이 기본값으로 변경되었다는 공식 릴리스 노트를 교차 확인하는 것을 권장한다. 이 시리즈의 76편·111편에서 MySQL 26.7의 캘린더 버전 전환과 주요 릴리스 사항을 다뤘으나, 통신 스택 기본값 변경은 MySQL 공식 문서에서 직접 확인이 필요하다.


References