구조 개요
이중 마스터(Dual Master)는 두 대의 MySQL 서버가 서로를 마스터로 인식하는 구조입니다. 양쪽 모두 읽기와 쓰기가 가능하며, 한쪽에 장애가 발생해도 다른 쪽으로 즉시 전환할 수 있습니다. 본 문서에서는 GTID 기반 복제를 활용한 이중 마스터 환경을 구성합니다.
실습 환경
| 역할 | IP 주소 | server-id |
|---|---|---|
| 노드 A | 10.53.207.20 | 20 |
| 노드 B | 10.53.207.21 | 21 |
핵심 설정: auto_increment 분리
양쪽 노드에서 동시에 쓰기가 발생할 때 PK 충돌을 방지하기 위해, 자동 증가 값을 분리합니다. 노드 A는 짝수, 노드 B는 홀수만 생성하도록 설정합니다.
노드 A 설정 (/etc/mysql/my.cnf)
[mysqld]
server-id = 20
gtid_mode = ON
enforce_gtid_consistency = ON
auto_increment_offset = 2
auto_increment_increment = 2
binlog_ignore_db = mysql
binlog_ignore_db = information_schema
binlog_ignore_db = performance_schema
binlog_ignore_db = sys
replicate_ignore_db = mysql
replicate_ignore_db = information_schema
replicate_ignore_db = performance_schema
replicate_ignore_db = sys노드 B 설정 (/etc/mysql/my.cnf)
[mysqld]
server-id = 21
gtid_mode = ON
enforce_gtid_consistency = ON
auto_increment_offset = 1
auto_increment_increment = 2
binlog_ignore_db = mysql
binlog_ignore_db = information_schema
binlog_ignore_db = performance_schema
binlog_ignore_db = sys
replicate_ignore_db = mysql
replicate_ignore_db = information_schema
replicate_ignore_db = performance_schema
replicate_ignore_db = sys서비스 재시작
systemctl restart mysql복제 전용 계정 생성
각 노드에서 독립적인 계정을 생성합니다. 계정명을 다르게 설정하면 충돌 위험을 줄일 수 있습니다.
CREATE USER 'sync_a'@'10.53.207.%' IDENTIFIED BY 'Sync#2024!A';
GRANT REPLICATION SLAVE ON *.* TO 'sync_a'@'10.53.207.%';
FLUSH PRIVILEGES;CREATE USER 'sync_b'@'10.53.207.%' IDENTIFIED BY 'Sync#2024!B';
GRANT REPLICATION SLAVE ON *.* TO 'sync_b'@'10.53.207.%';
FLUSH PRIVILEGES;노드 A에서 복제 구성
CHANGE MASTER TO
MASTER_HOST = '10.53.207.21',
MASTER_PORT = 3306,
MASTER_USER = 'sync_b',
MASTER_PASSWORD = 'Sync#2024!B',
MASTER_AUTO_POSITION = 1,
GET_MASTER_PUBLIC_KEY = 1;
START SLAVE;노드 B에서 복제 구성
CHANGE MASTER TO
MASTER_HOST = '10.53.207.20',
MASTER_PORT = 3306,
MASTER_USER = 'sync_a',
MASTER_PASSWORD = 'Sync#2024!A',
MASTER_AUTO_POSITION = 1,
GET_MASTER_PUBLIC_KEY = 1;
START SLAVE;상태 확인
SHOW REPLICA STATUS\G다음 두 항목이 모두 Yes여야 정상입니다.
Replica_IO_RunningReplica_SQL_Running
충돌 해결: GTID 스킵
계정 생성 문장이 반대편으로 복제되어 중복 오류가 발생할 수 있습니다. 이 경우 해당 GTID 트랜잭션을 건너뛰어 해결합니다.
-- 오류 발생 GTID 확인
SELECT @@GLOBAL.GTID_EXECUTED;
-- 복제 중지 및 예외 트랜잭션 스킵
STOP SLAVE;
SET GTID_NEXT = '7dad9e38-31c7-11ee-85dc-5254004bdc94:1';
BEGIN; COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
START SLAVE;주의사항: binlog_ignore_db의 한계
binlog_ignore_db와 replicate_ignore_db는 현재 선택된 데이터베이스에 따라 동작합니다. 예를 들어 sys 데이터베이스에 연결된 상태에서 mysql 데이터베이스의 사용자를 생성하면, 바이너리 로그에 기록되어 복제될 수 있습니다.
안전한 방법: 작업 전에 명시적으로 대상 데이터베이스를 선택합니다.
USE mysql;
CREATE USER 'app_user'@'%' IDENTIFIED BY 'SecurePass123!';검증
노드 A에서 테이블을 생성하고 데이터를 삽입한 뒤, 노드 B에서 조회해봅니다. 반대로 노드 B에서 데이터를 추가하고 노드 A에서 확인합니다.
-- 노드 A에서 실행
CREATE DATABASE IF NOT EXISTS demo;
USE demo;
CREATE TABLE items (
id INT AUTO_INCREMENT PRIMARY KEY,
label VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO items(label) VALUES ('node-a-item');-- 노드 B에서 실행
SELECT * FROM demo.items;
INSERT INTO items(label) VALUES ('node-b-item');-- 다시 노드 A에서 확인
SELECT * FROM demo.items;양쪽 모두 두 건의 데이터가 조회되면 이중 마스터 구성이 완료된 것입니다.