MySQL-MMM 기반 고가용성 구축 실전 가이드

MMM 개요 및 특징

MMM(Master-Master replication manager for MySQL)은 Perl 기반의 스크립트 집합으로, MySQL 마스터-마스터 복제 환경의 모니터링과 관리를 자동화합니다. 이름은 마스터-마스터이지만 실제 운영 시점에는 단일 노드만 쓰기를 수행하며, 나머지 마스터는 예비 상태로 일부 읽기 트래픽을 분담합니다. 이를 통해 장애 발생 시 빠른 전환과 노드 예열 효과를 동시에 얻을 수 있습니다.

MMM은 가상 IP 기반의 자동 장애 전환, 제 지연 모니터링, 슬레이브 로드 밸런싱 등을 제공합니다. 다만 완전한 데이터 일관성을 보장하지 못하므로, 최종 일관성이 허용되는 업무 환경에 적합합니다.

장단점 분석

강점:

  • 오랜 기간 검증된 안정적인 오픈소스 솔루션
  • MySQL 네이티브 기능 기반으로 원리 파악이 용이함
  • 설치 및 설정이 간편하며, HA와 failover를 포함한 풍부한 도구 제공
  • 클러스터 모드로 다수 MMM 그룹 중앙 관리 가능

약점:

  • 단일 쓰기 지점으로 인해 수평 확장성에 한계 존재
  • 읽기 분산은 별도 애플리케이션 로직 또는 추가 도구 필요

구성 환경

이번 구성에서는 5대 서버를 활용합니다.

호스트명IP 주소역할
primary-node10.0.0.11활성 마스터
standby-node10.0.0.12예비 마스터
replica-alpha10.0.0.13슬레이브
replica-beta10.0.0.14슬레이브
mmm-observer10.0.0.15모니터 서버

필요 가상 IP: 쓰기용 1개, 읽기용 4개

계정 권한 요구사항:

  • Monitor 계정: REPLICATION CLIENT, REPLICATION SLAVE
  • Agent 계정: SUPER, REPLICATION CLIENT, PROCESS
  • Replication 계정: REPLICATION SLAVE
  • Tools 계정: SUPER, REPLICATION CLIENT, RELOAD

MySQL 설치 및 설정

각 노드의 /etc/my.cnf 설정 예시입니다.

primary-node (10.0.0.11)

[mysqld]
server-id = 11
datadir = /var/lib/mysql/data
log-bin = /var/lib/mysql/logs/binlog
binlog_format = ROW
relay_log = /var/lib/mysql/logs/relay-log
auto-increment-increment = 2
auto-increment-offset = 1
sync_binlog = 1
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
max_binlog_size = 128M
log_slave_updates = 1
read_only = 1
sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

standby-node (10.0.0.12)

[mysqld]
server-id = 12
datadir = /var/lib/mysql/data
log-bin = /var/lib/mysql/logs/binlog
binlog_format = ROW
relay_log = /var/lib/mysql/logs/relay-log
auto-increment-increment = 2
auto-increment-offset = 2
sync_binlog = 1
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
max_binlog_size = 128M
log_slave_updates = 1
read_only = 1
sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

replica-alpha (10.0.0.13)

[mysqld]
server-id = 13
datadir = /var/lib/mysql/data
log-bin = /var/lib/mysql/logs/binlog
binlog_format = ROW
relay_log = /var/lib/mysql/logs/relay-log
sync_binlog = 1
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
max_binlog_size = 128M
log_slave_updates = 1
read_only = 1
sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

replica-beta (10.0.0.14)

[mysqld]
server-id = 14
datadir = /var/lib/mysql/data
log-bin = /var/lib/mysql/logs/binlog
binlog_format = ROW
relay_log = /var/lib/mysql/logs/relay-log
sync_binlog = 1
sync_master_info = 1
sync_relay_log = 1
sync_relay_log_info = 1
max_binlog_size = 128M
log_slave_updates = 1
read_only = 1
sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

설정 적용 후 각 서버에서 MySQL 서비스를 재시작합니다.

systemctl restart mysqld

필수 계정 생성 및 데이터 동기화

primary-node에서 계정을 생성합니다.

mysql -u root -p

CREATE USER 'mmm_observer'@'10.0.0.%' IDENTIFIED BY 'Secure#Pass1';
GRANT REPLICATION CLIENT ON *.* TO 'mmm_observer'@'10.0.0.%';

CREATE USER 'mmm_daemon'@'10.0.0.%' IDENTIFIED BY 'Secure#Pass1';
GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO 'mmm_daemon'@'10.0.0.%';

CREATE USER 'repl_sync'@'10.0.0.%' IDENTIFIED BY 'Secure#Pass1';
GRANT REPLICATION SLAVE ON *.* TO 'repl_sync'@'10.0.0.%';

데이터 일관성을 위해 잠금 후 백업을 수행합니다.

mysql -e "FLUSH TABLES WITH READ LOCK; SHOW MASTER STATUS;" > /tmp/master_info.txt
mysqldump --all-databases --single-transaction > /tmp/full_backup.sql
mysql -e "UNLOCK TABLES;"

백업 파일을 각 노드로 전송 후 복원합니다.

for node in standby-node replica-alpha replica-beta; do
    scp /tmp/full_backup.sql $node:/tmp/
    ssh $node "mysql < /tmp/full_backup.sql"
done

복제 연결 설정

standby-node, replica-alpha, replica-beta에서 primary-node를 마스터로 지정합니다.

CHANGE MASTER TO
    MASTER_HOST='10.0.0.11',
    MASTER_USER='repl_sync',
    MASTER_PASSWORD='Secure#Pass1',
    MASTER_LOG_FILE='binlog.000001',
    MASTER_LOG_POS=154;

START SLAVE;
SHOW SLAVE STATUS\G

primary-node에서 standby-node를 마스터로 지정하여 양방향 복제를 완성합니다.

-- standby-node의 바이너리 로그 위치 확인 후
CHANGE MASTER TO
    MASTER_HOST='10.0.0.12',
    MASTER_USER='repl_sync',
    MASTER_PASSWORD='Secure#Pass1',
    MASTER_LOG_FILE='binlog.000001',
    MASTER_LOG_POS=328;

START SLAVE;

MMM 설치 및 구성

모든 서버에서 전용 계정을 생성합니다.

useradd -s /sbin/nologin mmmd

저장소별 패키지 설치:

# 모니터 서버
yum install -y mysql-mmm-monitor

# 데이터베이스 서버 4대
yum install -y mysql-mmm-agent

공통 설정 파일: /etc/mysql-mmm/mmm_common.conf

active_master_role      writer

<host default>
    cluster_interface       eth0
    pid_path                /var/run/mysql-mmm/mmm_agentd.pid
    bin_path                /usr/libexec/mysql-mmm/
    replication_user        repl_sync
    replication_password    Secure#Pass1
    agent_user              mmm_daemon
    agent_password          Secure#Pass1
</host>

<host primary-node>
    ip      10.0.0.11
    mode    master
    peer    standby-node
</host>

<host standby-node>
    ip      10.0.0.12
    mode    master
    peer    primary-node
</host>

<host replica-alpha>
    ip      10.0.0.13
    mode    slave
</host>

<host replica-beta>
    ip      10.0.0.14
    mode    slave
</host>

<role writer>
    hosts   primary-node, standby-node
    ips     10.0.0.250
    mode    exclusive
</role>

<role reader>
    hosts   primary-node, standby-node, replica-alpha, replica-beta
    ips     10.0.0.251, 10.0.0.252, 10.0.0.253, 10.0.0.254
    mode    balanced
</role>

설정 파일을 모든 노드에 배포합니다.

for ip in 10.0.0.{11,12,13,14}; do
    scp /etc/mysql-mmm/mmm_common.conf $ip:/etc/mysql-mmm/
done

각 데이터베이스 서버의 에이전트 식별자를 설정합니다.

# primary-node 예시
echo "include mmm_common.conf
this primary-node" > /etc/mysql-mmm/mmm_agent.conf

모니터 서버 설정: /etc/mysql-mmm/mmm_mon.conf

include mmm_common.conf

<monitor>
    ip                  10.0.0.15
    pid_path            /var/run/mysql-mmm/mmm_mond.pid
    bin_path            /usr/libexec/mysql-mmm
    status_path         /var/lib/mysql-mmm/mmm_mond.status
    ping_ips            10.0.0.11, 10.0.0.12, 10.0.0.13, 10.0.0.14
    auto_set_online     60
</monitor>

<host default>
    monitor_user        mmm_observer
    monitor_password    Secure#Pass1
</host>

debug 0

서비스 기동

# 모니터 서버
chkconfig mysql-mmm-monitor on
service mysql-mmm-monitor start

# 데이터베이스 서버
chkconfig mysql-mmm-agent on
service mysql-mmm-agent start

장애 전환 검증

초기 클러스터 상태를 확인합니다.

mmm_control show

출력 예시:

primary-node(10.0.0.11) master/ONLINE. Roles: reader(10.0.0.251), writer(10.0.0.250)
standby-node(10.0.0.12) master/ONLINE. Roles: reader(10.0.0.254)
replica-alpha(10.0.0.13) slave/ONLINE. Roles: reader(10.0.0.252)
replica-beta(10.0.0.14) slave/ONLINE. Roles: reader(10.0.0.253)

primary-node의 MySQL을 중지하여 장애를 시뮬레이션합니다.

systemctl stop mysqld

모니터에서 상태를 확인하면 쓰기 VIP가 standby-node로 이동하고, primary-node는 HARD_OFFLINE 상태로 전환됩니다.

mmm_control show

primary-node(10.0.0.11) master/HARD_OFFLINE. Roles:
standby-node(10.0.0.12) master/ONLINE. Roles: reader(10.0.0.254), writer(10.0.0.250)
replica-alpha(10.0.0.13) slave/ONLINE. Roles: reader(10.0.0.251), reader(10.0.0.252)
replica-beta(10.0.0.14) slave/ONLINE. Roles: reader(10.0.0.253)

슬레이브들의 복제 마스터가 standby-node로 자동 재설정되었는지 확인합니다.

SHOW SLAVE STATUS\G
-- Master_Host: 10.0.0.12

장애 노드를 복구하면 자동으로 ONLINE 상태로 전환되나, 쓰기 역할은 기존 마스터를 유지합니다.

핵심 동작 원리

  • 가상 IP는 모니터 프로세스가 관리하며, 모니터 미구동 시에도 기존 할당된 VIP는 유지됨
  • 에이전트는 모니터의 지시에 따르며, 단독으로 장애를 처리할 수 없음
  • 모니터는 데이터베이스 상태, 서버 가용성, 복제 지연을 주기적으로 점검
  • 장애 복구 후 auto_set_online 시간(기본 60초) 경과 후 자동 ONLINE 전환
  • 모니터가 활성 마스터의 read_only를 OFF로, 나머지는 ON으로 설정함

운영 시 고려사항

예비 마스터 노드 장애는 클러스터에 영향을 주지 않으며, 단지 읽기 역할만 제거됩니다. 활성 마스터 장애 시 예비 마스터가 쓰기를 인수하고, 모든 슬레이브는 새 마스터를 자동 추적합니다.

다만 복제 지연이 발생한 상태에서 장애가 나면 데이터 불일치가 발생할 수 있습니다. 이를 완화하기 위해 반동기 복제(semi-sync replication) 적용을 권장하며, MariaDB 또는 MySQL 5.7 이상의 멀티스레드 슬레이브로 복제 성능을 향상시킬 수 있습니다.

태그: MySQL MySQL-MMM 고가용성 마스터-마스터복제 장애전환

5월 27일 21:30에 게시됨